Testing
Testing Operandi is straightforward. This guide covers strategies for unit testing your services effectively.
Basic Service Testing
Testing a Simple Service
# app/services/greet_service.rb
class GreetService < ApplicationService
arg :name, type: String
step :greet
output :message
private
def greet
self.message = "Hello, #{name}!"
end
end# spec/services/greet_service_spec.rb
RSpec.describe GreetService do
describe ".run" do
it "returns a greeting message" do
service = described_class.run(name: "John")
expect(service).to be_successful
expect(service.message).to eq("Hello, John!")
end
end
endTesting Success and Failure
Testing with Context
When services use context to share data, test both scenarios:
Testing Child Services in Context
When testing services that call other services via .with(self):
Testing Conditional Steps
Testing Early Exit with stop!
Testing Configuration Overrides
Testing run! vs run
Testing Warnings
Mocking External Services
Testing Argument Validation
Shared Examples for CRUD Services
Test Helpers
Create a helper module for common service testing patterns:
Custom RSpec Matchers
Operandi provides built-in RSpec matchers to make testing more expressive and readable.
Setup
Add this to your spec/spec_helper.rb or spec/rails_helper.rb:
This automatically includes all matchers in your RSpec tests.
DSL Definition Matchers
define_argument
define_argumentTest that a service defines specific arguments:
define_output
define_outputTest that a service defines specific outputs:
define_step and define_steps
define_step and define_stepsTest that a service defines specific steps:
Error and Warning Matchers
have_error_on and have_errors_on
have_error_on and have_errors_onTest service errors:
have_warning_on and have_warnings_on
have_warning_on and have_warnings_onTest service warnings:
Execution Matchers
These matchers require step tracking. Add this to your service:
execute_step and skip_step
execute_step and skip_stepexecute_steps and execute_steps_in_order
execute_steps and execute_steps_in_orderCallback Matchers
These matchers require callback tracking. Add this to your service:
trigger_callback
trigger_callbackWhat's Next?
Learn best practices for organizing your services:
Last updated