RSpec Matchers
Relevant source files
The following files were used as context for generating this wiki page:
RSpec Matchers in the sidekiq-unique-jobs project provide a domain-specific language for testing Sidekiq workers and their uniqueness configurations. These matchers allow developers to verify that workers are correctly configured with valid uniqueness options and to inspect the state of the Redis backing store during test execution.
The core of the RSpec integration is managed through the SidekiqUniqueJobs::RSpec::Matchers module, which is automatically included in RSpec configurations when RSpec is defined. This system ensures that workers adhere to the requirements of the unique jobs middleware, preventing runtime errors related to missing or invalid sidekiq_options.
Sources: lib/sidekiq_unique_jobs/rspec/matchers.rb:20-28, spec/spec_helper.rb:112-114
Worker Configuration Validation
The primary matcher provided for worker verification is have_valid_sidekiq_options. This matcher interacts with the SidekiqUniqueJobs.validate_worker method to ensure that a worker's configuration is compatible with the library's locking mechanisms.
Logic and Architecture
The validation process involves fetching the sidekiq_options from the worker class and passing them to a validation engine. The matcher fails if the worker lacks a :lock key or if the configuration contains invalid conflict strategies.
The diagram above shows the flow of worker validation from the RSpec expectation to the internal validation logic.
Sources: lib/sidekiq_unique_jobs/rspec/matchers/have_valid_sidekiq_options.rb:18-24, spec/sidekiq_unique_jobs/rspec/matchers/have_valid_sidekiq_options_spec.rb:10-15
Implementation Details
The HaveValidSidekiqOptions class captures the worker and its configuration, providing detailed error reporting if validation fails.
| Method | Description |
|---|---|
matches?(worker) | Orchestrates validation by calling validate_worker and checking valid? on the resulting config. |
failure_message | Formats errors from lock_config.errors_as_string into a readable RSpec failure. |
description | Returns the standard RSpec matcher description string. |
Sources: lib/sidekiq_unique_jobs/rspec/matchers/have_valid_sidekiq_options.rb:27-38
Redis and Queue Matchers
Internal testing support includes specialized matchers for verifying the state of Redis queues and job scheduling. These matchers utilize the SidekiqUniqueJobs.redis connection pool to inspect live data in the test environment.
Queue State Verification
The following matchers are defined to verify job counts and scheduling within Redis:
have_enqueued(number): Checks if a specific queue has the expected number of jobs usingconn.llen.be_enqueued_in(queue): Compares the length of a specific queue against an expected count.be_scheduled: Inspects thequeue:scheduleset to count jobs waiting for execution.be_scheduled_at(time): Useszcounton the "schedule" set to verify jobs scheduled for a specific timestamp.
Sources: spec/support/matchers/redis_matchers.rb:5-42
TTL Matcher
The have_ttl(seconds) matcher allows for precise verification of lock expiration times in Redis. It includes a .within(n) chain to handle slight variations in timing during test execution.
RSpec::Matchers.define :have_ttl do |seconds|
match do |key|
@ttl = ttl(key)
if @within
@range = ((seconds - @within)...(seconds + @within))
@range.cover?(@ttl)
else
@ttl == seconds
end
end
end
Sources: spec/support/matchers/redis_matchers.rb:44-63
RSpec Integration and Setup
The matchers are integrated into the test suite via spec_helper.rb. The project includes SidekiqUniqueJobs::Testing to provide helper methods that interact with these matchers.
Configuration Sequence
When RSpec is initialized, the middleware and matchers are configured as follows:
Summary
RSpec Matchers in sidekiq-unique-jobs serve as a critical tool for ensuring worker uniqueness is correctly implemented. By providing both high-level configuration validators like have_valid_sidekiq_options and low-level Redis state matchers like have_ttl, the library enables comprehensive testing of lock lifecycles and queue behavior. These tools prevent common configuration pitfalls, such as omitting the :lock option or using invalid conflict strategies, before code reaches production.