any_instance is not instance-agnostic when using receiver count expectation #58

Closed
wolframarnold opened this Issue May 16, 2011 · 12 comments

Comments

Projects
None yet
4 participants

I'm trying to set up a spec like this:

  class Calc
  end

  context "any_instance with receiver count expectation" do
    before do
      Calc.any_instance.should_receive(:add).twice
    end

    it 'should work with multiple instances' do
      Calc.new.add(1,2)
      Calc.new.add(2,3)
    end

This doesn't work, it generates an error:

RSpec::Mocks::MockExpectationError: The message 'add' was received by #<Calc:0x884cdc8> but has already been received by #<Calc:0x884f9d8>

I'm concluding that when using a receiver count expectation any_instance is specific to a given instance, counter to the assumption that any_instance really should work with any instance.

What I actually want to do is to be able to define multiple argument expectations with this, along the lines of:

Calc.any_instance.should_receive(:add).with(1,2).and_return(3)
Calc.any_instance.should_receive(:add).with(2,3).and_return(5)

That totally breaks down. The simple calculator example here is for illustration only, my actual issue is more complex and I can't easily compute the return value, but have to rely on table look-ups. In other words, I've not found a suitable work-around and I really need this behavior as described above, if it's supposed to be supported (which I'm not sure of).

I don't know if it matters: I'm doing this with Rails 3, RSpec 2.6, and Ree Ruby 1.8.7

Contributor

justinko commented May 16, 2011

Calc.any_instance.should_receive(:add).twice does work as expected. If it was called any_instances then the failure would make sense :)

However, the following should work as you would expect, and is a bug I'm currently looking at:

Calc.any_instance.should_receive(:add).with(1,2).and_return(3)
Calc.any_instance.should_receive(:add).with(2,3).and_return(5)

Thanks for the clarification and the discovery of the deeper but that wasn't apparent to me. Much appreciated.

justinko was assigned May 16, 2011

Contributor

justinko commented May 17, 2011

To the RSpec team, I'm currently working on a fix for this.

justinko closed this in 8e8e62f May 22, 2011

justinko reopened this May 31, 2011

Contributor

kaiwren commented May 31, 2011

The behaviour of any_instance in RSpec is 'exactly one instance', and not mocha's 'at least one instance' - see #48. I do however see how this breaks down in the absence of argument matchers which I'll take a stab at implementing.

I've not been actively tracking issues on rspec-mocks (I've been a little busy with RubyConf India these last few weeks) which is why I missed this ticket. Please feel free to send any any_instance related issues my way.

@kaiwren kaiwren added a commit to c42engineering/rspec-mocks that referenced this issue May 31, 2011

@kaiwren kaiwren split any_instance into multiple files and get to a green build as pr…
…ep to replicate issue #58
2de8024

@kaiwren kaiwren added a commit to c42engineering/rspec-mocks that referenced this issue May 31, 2011

@kaiwren kaiwren Added specs replicating issue #58 27367ce

@kaiwren kaiwren added a commit to c42engineering/rspec-mocks that referenced this issue Jun 8, 2011

@kaiwren kaiwren Looks like we've got issue #58 solved except the tests don't match th…
…e exception raised
fdbce6c
Contributor

kaiwren commented Jun 13, 2011

@alindeman Could you take a look at the issue58 branch if you have time to spare? I've got two specs that should catch an exception but aren't and I'm sorely in need of a pair that can look at the code and tell me what I'm missing.

Contributor

alindeman commented Jun 17, 2011

@kaiwren: Finally getting a chance to look at this; apologies on the delay.

Contributor

alindeman commented Jun 17, 2011

@kaiwren: An RSpec::Mocks::MockExpectationError is being caught and verified correctly in those two tests, but then the should_receive(:foo).with(:param_three, :param_four) expectation fails because, in the first test, the call caused an error and didn't satisfy the expectation .. and in the second test, a call with those arguments was not attempted at all.

It's the after(:each)-type callback that verifies should_receive expectations that's causing the failure, not the expect { }.to raise_error blocks.

Contributor

alindeman commented Jun 17, 2011

Submitted c42engineering#4 with a potential fix

Contributor

kaiwren commented Jun 17, 2011

@alindeman Ah, thanks for catching that. @justinko This should sort out the issue.

@kaiwren kaiwren added a commit to c42engineering/rspec-mocks that referenced this issue Jun 17, 2011

@kaiwren kaiwren Fixed broken feature related to multiple method stubs and added anoth…
…er for any_instance.stub.with - this should close Issue #58
e542b18
Contributor

alindeman commented Jun 17, 2011

Going to make a pull request against rspec/rspec-mocks?

Contributor

justinko commented Jun 17, 2011

@kaiwren - great! Just open up a new pull request please.

Contributor

kaiwren commented Jun 18, 2011

Oh yeah, sorry, just did that.

justinko closed this in 5a1666c Jun 19, 2011

justinko was unassigned by wolframarnold May 2, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment