# How to ensure signature compliance while mocking in ruby

**URL:** <https://www.ruby-forum.com/t/how-to-ensure-signature-compliance-while-mocking-in-ruby/120047>\
**Category:** Ruby\
**Created:** [November 13, 2007, 11:21am UTC](https://www.ruby-forum.com/t/how-to-ensure-signature-compliance-while-mocking-in-ruby/120047 "2007-11-13T11:21:37Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![pradeepgatram](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c6cbf5/32.png) [@pradeepgatram](https://www.ruby-forum.com/u/pradeepgatram)\
**Post date:** [November 13, 2007, 11:21am UTC](https://www.ruby-forum.com/t/how-to-ensure-signature-compliance-while-mocking-in-ruby/120047/1 "2007-11-13T11:21:37Z")

</div>

Let me put my dilemma as an example. Take a look at a snippet from  
FooTest.

#using mocha  
def test\_method1  
Bar.expects(:method2).with(‘param1’, ‘param2’).once  
Foo.method1  
end

And now the implementation

class Foo  
def self.method1  
Bar.method2(‘param1’, ‘param2’)  
end  
end

class Bar  
end

So far so good… Now my dilemma is that while implementing method2 in  
Bar, I can come up with any weird signature (e.g. def method2  
someInteger, someOtherNumber) and I will not be breaking FooTest. This  
obviously makes life hard while refactoring. Coming from a Java/C#  
background, I used to rely on compilation to catch these issues.

How have people solved such problems?

Pradeep

---

<div class="post-metadata">

**Author:** ![pradeepgatram](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c6cbf5/32.png) [@pradeepgatram](https://www.ruby-forum.com/u/pradeepgatram)\
**Post date:** [November 13, 2007, 2:18pm UTC](https://www.ruby-forum.com/t/how-to-ensure-signature-compliance-while-mocking-in-ruby/120047/2 "2007-11-13T14:18:53Z")

</div>

On 13/11/2007, Pradeep G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> And now the implementation  
> So far so good… Now my dilemma is that while implementing method2 in  
> Bar, I can come up with any weird signature (e.g. def method2  
> someInteger, someOtherNumber) and I will not be breaking FooTest. This  
> obviously makes life hard while refactoring. Coming from a Java/C#  
> background, I used to rely on compilation to catch these issues.
> 
> How have people solved such problems?
> 
> Pradeep

Hi Pradeep,  
Fundamentally you should never rely on only mock based tests, you should  
always have some functional tests to check all the objects are wired  
together correctly, but…

Mocha [1] used to only allow you to mock _existing_ methods on  
_concrete_  
classes. This functionality accidentally got removed a while ago, but  
I’d  
like to reintroduce it asap.

You can already restrict expecations on _mocks_ by using the  
responds\_like  
modifier [2], something like this…

class Foo  
def bar  
end  
end

def test\_me  
foo = mock(‘foo’)  
foo.responds\_like(Foo.new)  
foo.expects(:not\_bar)  
foo.not\_bar  
end

# =\> NoMethodError: undefined method `not\_bar’ for #Mock:foo which

responds like #Foo:0x432e5c

–  
James.

> **[James Mead](https://jamesmead.org/)**
>
> Ruby Developer, author of Mocha, and ex-Antarctic Hero.

> **[Floehopper](https://tumble.floehopper.org/)**
>
> thoughts on the bergy bits of life

[1] [http://mocha.rubyforge.org](http://mocha.rubyforge.org)  
[2] [http://mocha.rubyforge.org/classes/Mocha/Mock.html#M000032](http://mocha.rubyforge.org/classes/Mocha/Mock.html#M000032)

---

<div class="post-metadata">

**Author:** ![pradeepgatram](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c6cbf5/32.png) [@pradeepgatram](https://www.ruby-forum.com/u/pradeepgatram)\
**Post date:** [November 26, 2007, 1:54pm UTC](https://www.ruby-forum.com/t/how-to-ensure-signature-compliance-while-mocking-in-ruby/120047/3 "2007-11-26T13:54:15Z")

</div>

Hi James,

Sorry for vanishing for a couple of weeks. I have been using ur  
suggested approach of ‘responds\_like’. Although its a good start, it  
still does not give me complete confidence. All it tells me is whether  
the method is present or not. It does not guarantee signature  
compliance. For e.g., referring back to my example…

class Bar  
def method2 param1  
end  
end

The above implementation of method2 in Bar will cause FooTest to pass  
even with responds\_like. But the 2 parameter signature is clearly not  
supported.

I agree, an integration test should and will catch this scenario and  
will fail. But its not possible to write integration tests for every  
scenario. After all, the expected method call could happen under a  
convoluted condition. A classic case where, I believe, the unit tests  
should be able to give me complete guarantee of the state of code.

So there does appear to be a need for stricter checking. Leaving the  
default behaviour as is, maybe introduce a new method like  
mocked\_object.strictly\_expects(:blah)…

That leads me to another aspect? How about validating the return types  
:D. Java/C# again gave me that additional safety net of knowing that the  
return types were correct while I was mocking (at least thats what I  
remember).

Pradeep

---

<div class="post-metadata">

**Author:** ![pradeepgatram](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c6cbf5/32.png) [@pradeepgatram](https://www.ruby-forum.com/u/pradeepgatram)\
**Post date:** [January 2, 2008, 5:04pm UTC](https://www.ruby-forum.com/t/how-to-ensure-signature-compliance-while-mocking-in-ruby/120047/4 "2008-01-02T17:04:01Z")

</div>

On 26/11/2007, Pradeep G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The above implementation of method2 in Bar will cause FooTest to pass  
> even with responds\_like. But the 2 parameter signature is clearly not  
> supported.
> 
> I agree, an integration test should and will catch this scenario and  
> will fail. But its not possible to write integration tests for every  
> scenario. After all, the expected method call could happen under a  
> convoluted condition. A classic case where, I believe, the unit tests  
> should be able to give me complete guarantee of the state of code.

I don’t think you have to write an integration test for _every_  
scenario. I would aim to write just enough to give decent coverage of  
the integration points between classes, probably focussing on common  
or important business scenarios.

> So there does appear to be a need for stricter checking. Leaving the  
> default behaviour as is, maybe introduce a new method like  
> mocked\_object.strictly\_expects(:blah)…

I have considered something along these lines. I’ll give it some more  
thought. I’ve added a feature request on rubyforge [1].

> That leads me to another aspect? How about validating the return types  
> :D. Java/C# again gave me that additional safety net of knowing that the  
> return types were correct while I was mocking (at least thats what I  
> remember).

Hmm. I’m not sure how you are suggesting this could be achieved. Ruby  
methods do not declare their return type in the method declaration. I  
think the best way of obtaining the safety net you describe is to use  
integration tests. Alternatively you could go back to a statically  
typed language 😉

–  
James.

> **[James Mead](https://jamesmead.org/)**
>
> Ruby Developer, author of Mocha, and ex-Antarctic Hero.

> **[Floehopper](https://tumble.floehopper.org/)**
>
> thoughts on the bergy bits of life

[1]  
[http://rubyforge.org/tracker/index.php?func=detail&aid=16769&group\_id=1917&atid=7480](http://rubyforge.org/tracker/index.php?func=detail&aid=16769&group_id=1917&atid=7480)

---

<div class="post-metadata">

**Author:** ![pradeepgatram](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c6cbf5/32.png) [@pradeepgatram](https://www.ruby-forum.com/u/pradeepgatram)\
**Post date:** [November 13, 2007, 3:45pm UTC](https://www.ruby-forum.com/t/how-to-ensure-signature-compliance-while-mocking-in-ruby/120047/5 "2007-11-13T15:45:04Z")

</div>

On Nov 13, 2007 7:18 AM, James M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Mocha [1] used to only allow you to mock _existing_ methods on _concrete_  
> classes. This functionality accidentally got removed a while ago, but I’d  
> like to reintroduce it asap.

I beg of you, please don’t. At least not as a default behaviour.

Mocks are very powerful tools for interface discovery  
([http://www.jmock.org/oopsla2004.pdf](http://www.jmock.org/oopsla2004.pdf)). With an enforcement rule like  
the one you propose reinstating, we’d have to stop working on the  
object at hand to go write a class and/or method. This would break the  
flow of the current task, force us to shift focus.

Not only do we break the current flow, but by going over to the other  
object and sticking in a stub to get the mock to shut up, we run a far  
greater risk of leaving things 1/2 done than we do by sending  
unsupported messages and have our integration tests expose those  
holes.

For anybody who is serious about doing TDD, this would be a major step  
backwards.

What we’ve talked about adding to … ahem … another mocking  
library, is the ability engage this behaviour explicitly with an  
environment variable or a command line switch. That would provide the  
best of both worlds because you could stay focused on the task at hand  
AND you could get a report of the methods you don’t have on  
collaborating classes so you know where to go next.

I’d strongly recommend that you consider a similar path before simply  
forcing this rule on mocha users.

Cheers,  
David
