Skip to content

Commit

Permalink
Expect (failing) that any_instance.should_receive should fail if no
Browse files Browse the repository at this point in the history
instance is created during the course of an example.
  • Loading branch information
dchelimsky committed Mar 24, 2011
1 parent f0c1629 commit cb0475b
Showing 1 changed file with 89 additions and 67 deletions.
156 changes: 89 additions & 67 deletions spec/rspec/mocks/any_instance_spec.rb
Expand Up @@ -3,11 +3,12 @@
module RSpec
module Mocks
describe "#any_instance" do
class CustomErrorForTesting < StandardError;end
class CustomErrorForAnyInstanceSpec < StandardError;end

let(:klass) do
klass = Class.new
klass.class_eval{ def ooga;2;end }
klass
Class.new do
def existing_method; 2; end
end
end

context "invocation order" do
Expand Down Expand Up @@ -47,20 +48,20 @@ class CustomErrorForTesting < StandardError;end
end

context "with #stub" do
it "should not suppress an exception when a method that doesn't exist is invoked" do
it "does not suppress an exception when a method that doesn't exist is invoked" do
klass.any_instance.stub(:foo)
lambda{ klass.new.bar }.should raise_error(NoMethodError)
end

context "with #and_return" do
it "stubs a method that doesn't exist on any instance of a particular class" do
it "stubs a method that doesn't exist" do
klass.any_instance.stub(:foo).and_return(1)
klass.new.foo.should == 1
klass.new.foo.should eq(1)
end

it "stubs a method that exists on any instance of a particular class" do
klass.any_instance.stub(:ooga).and_return(1)
klass.new.ooga.should == 1
it "stubs a method that exists" do
klass.any_instance.stub(:existing_method).and_return(1)
klass.new.existing_method.should eq(1)
end

it "returns the same object for calls on different instances" do
Expand All @@ -75,110 +76,116 @@ class CustomErrorForTesting < StandardError;end
it "yields the value specified" do
yielded_value = Object.new
klass.any_instance.stub(:foo).and_yield(yielded_value)

klass.new.foo{|value| value.should be(yielded_value)}
end
end

context "with #and_raise" do
it "stubs a method that doesn't exist on any instance of a particular class" do
klass.any_instance.stub(:foo).and_raise(CustomErrorForTesting)
lambda{ klass.new.foo}.should raise_error(CustomErrorForTesting)
it "stubs a method that doesn't exist" do
klass.any_instance.stub(:foo).and_raise(CustomErrorForAnyInstanceSpec)
lambda{ klass.new.foo}.should raise_error(CustomErrorForAnyInstanceSpec)
end

it "stubs a method that exists on any instance of a particular class" do
klass.any_instance.stub(:ooga).and_raise(CustomErrorForTesting)
lambda{ klass.new.ooga}.should raise_error(CustomErrorForTesting)
it "stubs a method that exists" do
klass.any_instance.stub(:existing_method).and_raise(CustomErrorForAnyInstanceSpec)
lambda{ klass.new.existing_method}.should raise_error(CustomErrorForAnyInstanceSpec)
end
end

context "with a block" do
it "stubs a method on any instance of a particular class" do
it "stubs a method" do
klass.any_instance.stub(:foo) { 1 }
klass.new.foo.should == 1
klass.new.foo.should eq(1)
end

it "returns the same computed value for calls on different instances" do
klass.any_instance.stub(:foo) { 1 + 2 }
klass.new.foo.should == klass.new.foo
klass.new.foo.should eq(klass.new.foo)
end
end

context "core ruby objects" do
it "should work uniformly across *everything*" do
it "works uniformly across *everything*" do
Object.any_instance.stub(:foo).and_return(1)
Object.new.foo.should == 1
Object.new.foo.should eq(1)
end

it "should work with the non-standard constructor []" do
it "works with the non-standard constructor []" do
Array.any_instance.stub(:foo).and_return(1)
[].foo.should == 1
[].foo.should eq(1)
end

it "should work with the non-standard constructor {}" do
it "works with the non-standard constructor {}" do
Hash.any_instance.stub(:foo).and_return(1)
{}.foo.should == 1
{}.foo.should eq(1)
end

it "should work with the non-standard constructor \"\"" do
it "works with the non-standard constructor \"\"" do
String.any_instance.stub(:foo).and_return(1)
"".foo.should == 1
"".foo.should eq(1)
end

it "should work with the non-standard constructor \'\'" do
it "works with the non-standard constructor \'\'" do
String.any_instance.stub(:foo).and_return(1)
''.foo.should == 1
''.foo.should eq(1)
end

it "should work with the non-standard constructor module" do
it "works with the non-standard constructor module" do
Module.any_instance.stub(:foo).and_return(1)
module RSpec::SampleRspecTestModule;end
RSpec::SampleRspecTestModule.foo.should == 1
RSpec::SampleRspecTestModule.foo.should eq(1)
end

it "should work with the non-standard constructor class" do
it "works with the non-standard constructor class" do
Class.any_instance.stub(:foo).and_return(1)
class RSpec::SampleRspecTestClass;end
RSpec::SampleRspecTestClass.foo.should == 1
RSpec::SampleRspecTestClass.foo.should eq(1)
end
end
end

context "with #should_receive" do
context "when the method on which the expectation is set doesn't exist" do
context "when an expectation is set on a method does not exist" do
it "returns the expected value" do
klass.any_instance.should_receive(:foo).and_return(1)
klass.new.foo(1).should == 1
klass.new.foo(1).should eq(1)
end

it "fails the verification if an instance is created but no invocation occurs" do
it "fails if an instance is created but no invocation occurs" do
expect do
klass.any_instance.should_receive(:foo)
klass.new.rspec_verify
instance = klass.new
instance.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end

it "does nothing if no instance is created" do
klass.any_instance.should_receive(:foo).and_return(1)
it "fails if no instance is created" do
expect do
klass.any_instance.should_receive(:foo).and_return(1)
klass.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end
end

context "when an expectation is set on a method that exists" do
it "returns the expected value" do
klass.any_instance.should_receive(:ooga).and_return(1)
klass.new.ooga(1).should == 1
klass.any_instance.should_receive(:existing_method).and_return(1)
klass.new.existing_method(1).should eq(1)
end

it "fails the verification if an instance is created but no invocation occurs" do
it "fails if an instance is created but no invocation occurs" do
expect do
klass.any_instance.should_receive(:ooga)
klass.any_instance.should_receive(:existing_method)
instance = klass.new
instance.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end

it "does nothing if no instance is created" do
klass.any_instance.should_receive(:ooga).and_return(1)
it "fails if no instance is created" do
expect do
klass.any_instance.should_receive(:existing_method).and_return(1)
klass.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end
end

Expand All @@ -199,11 +206,26 @@ class RSpec::SampleRspecTestClass;end
instance.foo
end

it "fails when no instances are declared" do
expect do
klass.any_instance.should_receive(:foo).once
klass.new.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end

it "fails when an instance is declared but there are no invocations" do
expect do
klass.any_instance.should_receive(:foo).once
instance = klass.new
klass.new.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end

it "fails for more than one invocation" do
expect do
klass.any_instance.should_receive(:foo).once
instance = klass.new
2.times{ instance.foo }
2.times { instance.foo }
instance.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end
Expand All @@ -213,14 +235,14 @@ class RSpec::SampleRspecTestClass;end
it "passes for two invocations" do
klass.any_instance.should_receive(:foo).twice
instance = klass.new
2.times{ instance.foo }
2.times { instance.foo }
end

it "fails for more than two invocations" do
expect do
klass.any_instance.should_receive(:foo).twice
instance = klass.new
3.times{ instance.foo }
3.times { instance.foo }
instance.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end
Expand All @@ -230,14 +252,14 @@ class RSpec::SampleRspecTestClass;end
it "passes for n invocations where n = 3" do
klass.any_instance.should_receive(:foo).exactly(3).times
instance = klass.new
3.times{ instance.foo }
3.times { instance.foo }
end

it "fails for n invocations where n < 3" do
expect do
klass.any_instance.should_receive(:foo).exactly(3).times
instance = klass.new
2.times{ instance.foo }
2.times { instance.foo }
instance.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end
Expand All @@ -246,7 +268,7 @@ class RSpec::SampleRspecTestClass;end
expect do
klass.any_instance.should_receive(:foo).exactly(3).times
instance = klass.new
4.times{ instance.foo }
4.times { instance.foo }
instance.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end
Expand All @@ -256,43 +278,43 @@ class RSpec::SampleRspecTestClass;end
it "passes for n invocations where n = 3" do
klass.any_instance.should_receive(:foo).at_least(3).times
instance = klass.new
3.times{ instance.foo }
3.times { instance.foo }
end

it "fails for n invocations where n < 3" do
expect do
klass.any_instance.should_receive(:foo).at_least(3).times
instance = klass.new
2.times{ instance.foo }
2.times { instance.foo }
instance.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end

it "passes for n invocations where n > 3" do
klass.any_instance.should_receive(:foo).at_least(3).times
instance = klass.new
4.times{ instance.foo }
4.times { instance.foo }
end
end

context "the 'at_most(n)' constraint" do
it "passes for n invocations where n = 3" do
klass.any_instance.should_receive(:foo).at_most(3).times
instance = klass.new
3.times{ instance.foo }
3.times { instance.foo }
end

it "passes for n invocations where n < 3" do
klass.any_instance.should_receive(:foo).at_most(3).times
instance = klass.new
2.times{ instance.foo }
2.times { instance.foo }
end

it "fails for n invocations where n > 3" do
expect do
klass.any_instance.should_receive(:foo).at_most(3).times
instance = klass.new
4.times{ instance.foo }
4.times { instance.foo }
instance.rspec_verify
end.to raise_error(RSpec::Mocks::MockExpectationError)
end
Expand All @@ -301,15 +323,14 @@ class RSpec::SampleRspecTestClass;end
context "the 'never' constraint" do
it "passes for 0 invocations" do
klass.any_instance.should_receive(:foo).never
klass.new
instance = klass.new
instance.rspec_verify
end

it "fails on the first invocation" do
expect do
klass.any_instance.should_receive(:foo).never
instance = klass.new
instance.foo
instance.rspec_verify
klass.new.foo
end.to raise_error(RSpec::Mocks::MockExpectationError)
end
end
Expand All @@ -324,6 +345,7 @@ class RSpec::SampleRspecTestClass;end
klass.any_instance.should_receive(:foo).any_number_of_times
instance = klass.new
instance.foo
instance.rspec_verify
end
end
end
Expand All @@ -334,21 +356,21 @@ class RSpec::SampleRspecTestClass;end
space = RSpec::Mocks::Space.new
space.add(klass)

klass.any_instance.stub(:ooga).and_return(1)
klass.should be_method_defined(:__ooga_without_any_instance__)
klass.any_instance.stub(:existing_method).and_return(1)
klass.method_defined?(:__existing_method_without_any_instance__).should be_true

space.reset_all

klass.should_not be_method_defined(:__ooga_without_any_instance__)
klass.new.ooga.should == 2
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
klass.new.existing_method.should eq(2)
end

it "adds an class to the current space when #any_instance is invoked" do
klass.any_instance
RSpec::Mocks::space.send(:mocks).should include(klass)
end

it "adds an instance to the current space" do
it "adds an instance to the current space when stubbed method is invoked" do
klass.any_instance.stub(:foo)
instance = klass.new
instance.foo
Expand Down

1 comment on commit cb0475b

@alindeman
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need any help getting these specs to pass? If so, I can likely make some time tomorrow.

Please sign in to comment.