spec/rspec/mocks/any_instance_spec.rb in rspec-mocks-2.99.4 vs spec/rspec/mocks/any_instance_spec.rb in rspec-mocks-3.0.0.beta1

- old
+ new

@@ -35,27 +35,27 @@ expect { klass.any_instance.stub(:foo).and_yield(1).with("1") }.to raise_error(NoMethodError) end end context "#stub_chain" do - it "raises an error if 'stub_chain' follows 'any_instance'" do + it "raises an error if 'stub_chain' follows 'and_return'" do expect { klass.any_instance.and_return("1").stub_chain(:foo, :bar) }.to raise_error(NoMethodError) end end context "#should_receive" do it "raises an error if 'should_receive' follows 'with'" do expect { klass.any_instance.with("1").should_receive(:foo) }.to raise_error(NoMethodError) end it "raises an error if 'with' follows 'and_return'" do - skip "see Github issue #42" + pending "see Github issue #42" expect { klass.any_instance.should_receive(:foo).and_return(1).with("1") }.to raise_error(NoMethodError) end it "raises an error if 'with' follows 'and_raise'" do - skip "see Github issue #42" + pending "see Github issue #42" expect { klass.any_instance.should_receive(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError) end end end @@ -212,12 +212,10 @@ expect { klass.new.existing_method}.to raise_error(CustomErrorForAnyInstanceSpec) end end context "with a block" do - before { allow_unavoidable_1_8_deprecation } - it "stubs a method" do klass.any_instance.stub(:foo) { 1 } expect(klass.new.foo).to eq(1) end @@ -225,10 +223,28 @@ klass.any_instance.stub(:foo) { 1 + 2 } expect(klass.new.foo).to eq(klass.new.foo) end end + context "when partially mocking objects" do + let(:obj) { klass.new } + + it "resets partially mocked objects correctly" do + allow_any_instance_of(klass).to receive(:existing_method).and_return("stubbed value") + + # Simply resetting the proxy doesn't work + # what we need to have happen is + # ::RSpec::Mocks.any_instance_recorder_for(klass).stop_all_observation! + # but that is never invoked in :: + expect { + RSpec::Mocks.space.verify_all + }.to( + change { obj.existing_method }.from("stubbed value").to(:existing_method_return_value) + ) + end + end + context "core ruby objects" do it "works uniformly across *everything*" do Object.any_instance.stub(:foo).and_return(1) expect(Object.new.foo).to eq(1) end @@ -265,26 +281,10 @@ expect(RSpec::SampleRspecTestClass.foo).to eq(1) end end end - context "with #stub!" do - it "raises with a message instructing the user to use stub instead" do - expect do - klass.any_instance.stub!(:foo) - end.to raise_error(/Use stub instead/) - end - end - - context "with #unstub!" do - it "raises with a message instructing the user to use unstub instead" do - expect do - klass.any_instance.unstub!(:foo) - end.to raise_error(/Use unstub instead/) - end - end - context "unstub implementation" do it "replaces the stubbed method with the original method" do klass.any_instance.stub(:existing_method) klass.any_instance.unstub(:existing_method) expect(klass.new.existing_method).to eq(:existing_method_return_value) @@ -375,11 +375,10 @@ it 'passes if only the expected message is received' do klass.any_instance.should_receive(:foo) klass.any_instance.should_not_receive(:bar) klass.new.foo RSpec::Mocks.space.verify_all - RSpec::Mocks.space.reset_all end end it "prevents confusing double-negative expressions involving `never`" do expect { @@ -398,40 +397,28 @@ expect(klass.new.foo(1)).to eq(1) end it "fails if an instance is created but no invocation occurs" do expect do - begin - klass.any_instance.should_receive(:foo) - klass.new - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:foo) + klass.new + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message) end it "fails if no instance is created" do expect do - begin - klass.any_instance.should_receive(:foo).and_return(1) - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:foo).and_return(1) + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message) end it "fails if no instance is created and there are multiple expectations" do expect do - begin - klass.any_instance.should_receive(:foo) - klass.any_instance.should_receive(:bar) - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:foo) + klass.any_instance.should_receive(:bar) + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: bar, foo') end it "allows expectations on instances to take priority" do klass.any_instance.should_receive(:foo) @@ -489,40 +476,28 @@ expect(klass.new.existing_method(1)).to eq(1) end it "fails if an instance is created but no invocation occurs" do expect do - begin - klass.any_instance.should_receive(:existing_method) - klass.new - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:existing_method) + klass.new + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message) end it "fails if no instance is created" do expect do - begin - klass.any_instance.should_receive(:existing_method) - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:existing_method) + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message) end it "fails if no instance is created and there are multiple expectations" do expect do - begin - klass.any_instance.should_receive(:existing_method) - klass.any_instance.should_receive(:another_existing_method) - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:existing_method) + klass.any_instance.should_receive(:another_existing_method) + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: another_existing_method, existing_method') end context "after any one instance has received a message" do it "passes if subsequent invocations do not receive that message" do @@ -611,28 +586,20 @@ klass.new.foo end it "fails when no instances are declared" do expect do - begin - klass.any_instance.should_receive(:foo).once - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:foo).once + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message) end it "fails when an instance is declared but there are no invocations" do expect do - begin - klass.any_instance.should_receive(:foo).once - klass.new - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:foo).once + klass.new + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message) end it "fails for more than one invocation" do expect do @@ -753,63 +720,17 @@ expect(klass.new.existing_method).to eq(5) end it "fails when the other expecations are not met" do expect do - begin - klass.any_instance.should_receive(:foo).never - klass.any_instance.should_receive(:existing_method).and_return(5) - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end + klass.any_instance.should_receive(:foo).never + klass.any_instance.should_receive(:existing_method).and_return(5) + RSpec::Mocks.space.verify_all end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message) end end end - - context "the 'any_number_of_times' constraint" do - it "passes for 0 invocations" do - klass.any_instance.should_receive(:foo).any_number_of_times - verify klass.new - end - - it "passes for a non-zero number of invocations" do - allow(RSpec).to receive(:deprecate).with("any_number_of_times", :replacement => "stub") - - klass.any_instance.should_receive(:foo).any_number_of_times - instance = klass.new - instance.foo - verify instance - end - - it "does not interfere with other expectations" do - klass.any_instance.should_receive(:foo).any_number_of_times - klass.any_instance.should_receive(:existing_method).and_return(5) - expect(klass.new.existing_method).to eq(5) - end - - context "when combined with other expectations" do - it "passes when the other expecations are met" do - klass.any_instance.should_receive(:foo).any_number_of_times - klass.any_instance.should_receive(:existing_method).and_return(5) - expect(klass.new.existing_method).to eq(5) - end - - it "fails when the other expecations are not met" do - expect do - begin - klass.any_instance.should_receive(:foo).any_number_of_times - klass.any_instance.should_receive(:existing_method).and_return(5) - RSpec::Mocks.space.verify_all - ensure - RSpec::Mocks.space.reset_all - end - end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message) - end - end - end end end context "when resetting post-verification" do let(:space) { RSpec::Mocks.space } @@ -821,56 +742,52 @@ context "with stubbing" do context "public methods" do before(:each) do klass.any_instance.stub(:existing_method).and_return(1) - expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be true + expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_truthy end it "restores the class to its original state after each example when no instance is created" do space.verify_all - space.reset_all - expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be false + expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey expect(klass.new.existing_method).to eq(existing_method_return_value) end it "restores the class to its original state after each example when one instance is created" do klass.new.existing_method space.verify_all - space.reset_all - expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be false + expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey expect(klass.new.existing_method).to eq(existing_method_return_value) end it "restores the class to its original state after each example when more than one instance is created" do klass.new.existing_method klass.new.existing_method space.verify_all - space.reset_all - expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be false + expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey expect(klass.new.existing_method).to eq(existing_method_return_value) end end context "private methods" do before :each do klass.any_instance.stub(:private_method).and_return(:something) space.verify_all - space.reset_all end it "cleans up the backed up method" do - expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be false + expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey end it "restores a stubbed private method after the spec is run" do - expect(klass.private_method_defined?(:private_method)).to be true + expect(klass.private_method_defined?(:private_method)).to be_truthy end it "ensures that the restored method behaves as it originally did" do expect(klass.new.send(:private_method)).to eq(:private_method_return_value) end @@ -881,19 +798,18 @@ context "private methods" do before :each do klass.any_instance.should_receive(:private_method).and_return(:something) klass.new.private_method space.verify_all - space.reset_all end it "cleans up the backed up method" do - expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be false + expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey end it "restores a stubbed private method after the spec is run" do - expect(klass.private_method_defined?(:private_method)).to be true + expect(klass.private_method_defined?(:private_method)).to be_truthy end it "ensures that the restored method behaves as it originally did" do expect(klass.new.send(:private_method)).to eq(:private_method_return_value) end @@ -929,11 +845,10 @@ it "ensures that the next spec does not see that expectation" do klass.any_instance.should_receive(:existing_method).and_return(Object.new) klass.new.existing_method space.verify_all - space.reset_all expect(klass.new.existing_method).to eq(existing_method_return_value) end end end @@ -942,11 +857,10 @@ it "does not prevent the change from being rolled back" do klass.any_instance.stub(:existing_method).and_return(false) klass.any_instance.stub(:existing_method).and_return(true) RSpec::Mocks.space.verify_all - RSpec::Mocks.space.reset_all expect(klass.new).to respond_to(:existing_method) expect(klass.new.existing_method).to eq(existing_method_return_value) end end @@ -1032,130 +946,10 @@ klass.any_instance.should_receive(:bees).with(:faces) instance.bees(:faces) end end end - - context "by default" do - def block_regex(line) - /as the first block argument.*#{__FILE__}:#{line}/m - end - - it "is off" do - expect(RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks?).to be false - end - - it "will warn about allowances receiving blocks in 3.0" do - klass = Struct.new(:bees) - - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 1)) - allow_any_instance_of(klass).to receive(:foo) { |args| } - klass.new(:faces).foo - end - - it "will warn about expectations receiving blocks in 3.0" do - klass = Struct.new(:bees) - - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 1)) - expect_any_instance_of(klass).to receive(:foo) { |args| } - klass.new(:faces).foo - end - - it 'includes the line of the block declaration in the warning, ' + - 'even when it is different from the `any_instance` line', :unless => (RUBY_VERSION.to_f < 1.9) do - klass = Class.new - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 3)) - stub = klass.any_instance.stub(:foo) - - stub.with("bar") { |args| } - klass.new.foo("bar") - end - - it "will warn about expectations receiving blocks with a times restriction" do - klass = Struct.new(:bees) - - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 1)) - klass.any_instance.should_receive(:foo).exactly(3).times { |a| :some_return_value } - - instance = klass.new(:faces) - 3.times { instance.foo } - end - - it "will warn about expectations receiving blocks with an argument expectation" do - klass = Struct.new(:bees) - - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 1)) - klass.any_instance.should_receive(:foo).with(3) { |b| :some_return_value } - - instance = klass.new(:faces) - instance.foo(3) - end - - it "works with a do end style block" do - klass = Struct.new(:bees) - - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 1)) - klass.any_instance.should_receive(:foo).with(3) do |a| - :some_return_value - end - - instance = klass.new(:faces) - instance.foo(3) - end - - it "won't warn if there is no implementation block on an expectation" do - expect(RSpec).not_to receive(:warn_deprecation) - - klass = Struct.new(:bees) - - allow_any_instance_of(klass).to receive(:foo) - klass.new(:faces).foo - end - - it "won't warn if the implementation block ignores arguments", :if => (RUBY_VERSION.to_f > 1.8) do - expect(RSpec).not_to receive(:warn_deprecation) - - klass = Struct.new(:bees) - allow_any_instance_of(klass).to receive(:foo) { 5 } - klass.new(:faces).foo - end - - it "warns if the implementation block accepts a splat" do - klass = Struct.new(:bees) - - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 1)) - allow_any_instance_of(klass).to receive(:foo) { |*a| 5 } - - klass.new(:faces).foo - end - - it "warns if it the implementation is a lambda that expects no arguments" do - klass = Struct.new(:bees) - - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 1)) - allow_any_instance_of(klass).to receive(:foo, &lambda { 5 }) - - klass.new(:faces).foo - end - - it "will warn about stubs receiving blocks in 3.0" do - klass = Struct.new(:bees) - - expect(RSpec).to receive(:warn_deprecation).with(block_regex(__LINE__ + 1)) - expect_any_instance_of(klass).to receive(:foo) { |args| } - klass.new(:faces).foo - end - - it "won't warn if there is no implementation block on an stub" do - expect(RSpec).not_to receive(:warn_deprecation) - - klass = Struct.new(:bees) - - allow_any_instance_of(klass).to receive(:foo) - klass.new(:faces).foo - end - end end context 'when used in conjunction with a `dup`' do it "doesn't cause an infinite loop" do pending "This intermittently fails on JRuby" if RUBY_PLATFORM == 'java' @@ -1224,10 +1018,9 @@ instance = klass.new expect(instance.existing_method).to eq :stubbed_return_value RSpec::Mocks.verify - RSpec::Mocks.teardown expect(instance.existing_method).to eq :existing_method_return_value end end end