Glenn JahnkeGlenn Jahnke
Standup 8/12/2009: Using stub with before(:all)
edit Posted by Glenn Jahnke on Wednesday August 12, 2009 at 05:43PM

Ask for Help

"My method stub only works on the first RSpec example and clearing in subsequent examples, what's wrong?"

Using RSpec, it is common to mock out certain aspects of your code to change functionality for testing. This is accomplished using the "stub" method and passing the method name as a symbol.

SomeObject.stub(:some_method_to_modify).and_return do something_else() end

As we like to keep our code nice and DRY, we often pull things into "before" blocks. Unfortunately, this can cause some confusion as

describe "ObjectA" do
    before :all do
        ObjectB.stub!(:some_method_ObjectA_depends_on).and_return(15)
    end

    it "can test something" do
        ...
    end

    it "can test something else" do
        Objectb.some_method_ObjectA_depends_on
    end

end

will have ObjectB.some_method_ObjectA_depends_on actually executing ObjectB's method instead of stubbing. This is because after each example ("it" block), all stubs are cleared from all objects, leaving the stubs only effective in the first example.

Comments

  1. Chad Woolley Chad Woolley on August 14, 2009 at 02:00AM

    Why aren't you using 'before :each' (which is the no-param default for 'before') instead of 'before :all'? This behavior makes sense to me - mocks must be cleared out after each example; having stubs do the same is logical.

    You can also have both 'before :all' and 'before :each' blocks in your specs (see the rspec docs), so any mocking/stubbing should be done in a 'before :each'.

    Out of curiosity, why did you need 'before :all'? I don't think I've ever needed to use it...

  2. Glenn Jahnke Glenn Jahnke on August 14, 2009 at 09:28AM

    @Chad, I don't know why the person at standup was using them, but perhaps they were doing some expensive but necessary test setup like downloading a file or doing a complex database query that must happen before the tests, but only once because the data is not modified.