[rspec-users] modules and stub

David Chelimsky
Mon, 25 May 2009 04:54:54 -0000

On Mon, May 25, 2009 at 12:03 AM, Sarah Allen <lists at ruby-forum.com>
wrote:
> David Chelimsky wrote:
>> Stub methods on objects, not modules. The method can be one that
>> *comes from* a module, but you need to stub it on the specific object
>> that is at play in the example.
>
> That makes sense, except the code does this:
> ?Foo::Bar::do_something(path)
>
> I''m not an expert with modules, but that looks like it is calling
the
> method directly on the module without an object.

You''re correct.

> Is there any way for me to stub that?

You can stub that like this:

Foo::Bar.stub(:do_something)

> or is that not a good thing to be doing?

This really depends on a lot of different factors. Whether Bar is a
module or a class, do_something is essentially a global, and globals
are *generally* problematic for testing because they increase the risk
of leaking state from example to example. That said, the four mock
frameworks supported directly by rspec (rspec, mocha, flexmock and rr)
all roll back stubs after each example and they all seem to work just
fine. Therefore that risk is mitigated. But that doesn''t mean
it''s
100% risk-free. Ruby is very flexible and powerful, and just as
mock/stub frameworks can momentarily change an object''s behaviour, so
can any library code or application code.

If you stub, for example, do_something on this module, but it turns
out that do_something gets added to the module through some dynamic
means *after the stub declaration*, the stub declaration will be
overwritten and you''ll get surprising results. This is not just true
of globals - it''s true of any methods that appear through the magic of
metaprogramming.

HTH,
David

> Thanks,