Dawid Pura
Dawid Pura

Reputation: 1029

How to stub whole module using Mocha?

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

Answers (1)

Franck Verrot
Franck Verrot

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

Related Questions