Gordon Seidoh Worley
Gordon Seidoh Worley

Reputation: 8068

Complex RSpec Argument Testing

I have a method I want to test that is being called with a particular object. However, identifying this object is somewhat complex because I'm not interested in a particular instance of the object, but one that conforms to certain conditions.

For example, my code might be like:

some_complex_object = ComplexObject.generate(params)
my_function(some_complex_object)

And in my test I want to check that

test_complex_object = ComplexObject.generate(test_params)
subject.should_receive(:my_function).with(test_complex_object)

But I definitely know that ComplexObject#== will return false when comparing some_complex_object and test_complex_object because that is desired behavior (elsewhere I rely on standard == behavior and so don't want to overload it for ComplexObject).

I would argue that it's a problem that I find myself needing to write a test such as this, and would prefer to restructure the code so that I don't need to write such a test, but that's unfortunately a much larger task that would require rewriting a lot of existing code and so is a longer term fix that I want to get to but can't do right now within time constraints.

Is there a way with Rspec to be able to do a more complex comparison between arguments in a test? Ideally I'd like something where I could use a block so I can write arbitrary comparison code.

Upvotes: 4

Views: 561

Answers (1)

Peter Alfvin
Peter Alfvin

Reputation: 29399

See https://www.relishapp.com/rspec/rspec-mocks/v/2-7/docs/argument-matchers for information on how you can provide a block to do arbitrary analysis of the arguments passed to a method, as in:

expect(subject).to receive(:my_function) do |test_complex_object|
   # code setting expectations on test_complex_object
end

You can also define a custom matcher which will let you evaluate objects to see if that satisfy the condition, as described in https://www.relishapp.com/rspec/rspec-expectations/v/2-3/docs/custom-matchers/define-matcher

Upvotes: 5

Related Questions