Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

setups get run multiple times, big issue with RR #31

Closed
DouglasMeyer opened this Issue · 7 comments

4 participants

@DouglasMeyer

Hey Guys-

I ran into this issue when I was using a RR mock in a parent context's setup (see example).

require '.....'
context "bla" do
  setup do
    puts "SETUP"
    Object.new.tap do |obj
      mock(obj).something{ true }
    end
  end
  context "a context" do
    should :something
  end
end

Output:

SETUP
bla a context
SETUP
  - should something: something() Called 0 times. Expected 1 times.

It looks like the setup is getting called for the bla context, then once again for the a context context. I would guess a way to fix this is to not have the contexts run the setups and teardowns, but have the "runnables" run them.

Thanks,
-Doug

@achiu
Collaborator

The parent context setup are ran again within each child context. So your a context context is going to setup the mocks again. One way you can avoid this is to do the mocking within the assertion that your testing, or not nest the context that you don't want the mocking to be also ran on.

@DouglasMeyer

You may be right in the case of the example, but it is still an issue that riot needlessly runs setup/teardown multiple times. This issue is easily missed unless the setup/teardown takes a while or you use RR.

@toothrot
Owner

This is actually intentional: here is an example from an old discussion

If you think about it, each context is sort of its own world. The sub-context has to re-run them since the previous context will have cleaned up after itself in its teardowns, ideally.

@DouglasMeyer

Ok, I think I have a good idea of the model. So it looks like this isn't so much an issue with contexts as it is how RR is used. As this example should show, if there aren't any assertions in the parent context, the expectations from the setup are never reset.

@gus
Owner

Hey Doug,

Sorry for the much belated response. I agree with you that there is a problem. The tests should pass whether you comment out the first should :get_mocked_once or not.

What's strange is that if I do this, it works:

require 'rubygems'
require 'riot'
require 'riot/rr'

context "riot sanity test" do
  #setup do
    #puts "SETUP"
    #Object.new.tap do |obj|
      #mock(obj).get_mocked_once{ true }
    #end
  #end

  #un-comment this next line and the tests magically pass
  #should :get_mocked_once
  context "generic context" do
    setup do
      puts "SETUP"
      Object.new.tap do |obj|
        mock(obj).get_mocked_once{ true }
      end
    end

    should "call get mocked once" do 
      topic.get_mocked_once
    end
  end
end

Taking a look.

@gus
Owner

Even "funnier" is this:

require 'rubygems'
require 'riot'
require 'riot/rr'

context "riot sanity test" do
  setup do
    puts "SETUP"
    Object.new.tap do |obj|
      mock(obj).get_mocked_once{ puts "here"; true }
      puts obj.inspect
    end
  end

  #should :get_mocked_once

  context "with subcontext" do
    should "x" do
      topic.get_mocked_once
      topic.get_mocked_once
    end
  end
end

Which generates this message:

situation/on
SETUP
riot sanity test with subcontext
SETUP
  ! should x: get_mocked_once()
Called 2 times.
Expected 1 times.

0 passes, 0 failures, 1 errors in 0.005137 seconds

So, in this case it sees that's it been called two times. Quite fishy indeed.

@DouglasMeyer

Thanks for looking into this inconsistency.

@gus gus closed this issue from a commit
@gus gus close #31 - reset RR situation on initialize
I don't yet understand what's going on in RR that caused the issue and
necessitated this fix yet, but it is at least fixed.
0ac61bf
@gus gus closed this in 0ac61bf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.