Reputation: 1029
I have a complex module used in my implementation with some functions in it.
module A
def function some_params
#returns some chain object
end
end
#implementation
class SomeImplementation
def some_function some_params
A.function(some_params_other).function1
end
end
I want to stub it by my class:
class AStub
def function params
#rely on params
do_something_else_return_same_object
end
def function1
other_do
end
end
How i can do it? In particular how to replace A to being my class using Mocha. Any thoughts? I can't do that:
A.stubs(:function)
because there is no way to catch first parameters (i need them to define next behavior).
Upvotes: 0
Views: 1091
Reputation: 1041
To answer your question, here's how to do it (from the docs and from what I understand of your problem, so I might have it wrong):
A.expects(:function).with(<some params>).returns(AStub)
A.expects(:function).with(<some other params>).returns(AnotherStub)
But IMHO, I think it really boils down to how you want to design you code.
You basically want to have A
replaced by a mock for your tests but you could actually have it "injected" using other techniques (and then use mocha traditionally).
Here are some techniques I would use:
1. Pass the module specifically to that method using a default parameter:
class SomeImplementation
def some_function <some_params>, a_obj = A
a_obj.function(some_params_other).function1
end
end
So that you would need do something like
SomeImplementation.new.some_function(some_params, your_test_double_for(A))
2. Pass the module for the whole object:
class SomeImplementation
def initialize(some_obj_params, a_obj = A)
@a_obj = a_obj
end
def some_function some_params
@a_obj.function(some_params_other).function1
end
end
In that case you'd write:
SomeImplementation.new(your_test_double_for(A)).some_function(some_params)`
Also, when given the choice, I avoid using modules as they're harder to work with when you're "really" using TDD (by "really" I just mean "discovering the emergent design while you code).
Upvotes: 2