rspec-mocks 3.0.0.beta2 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +104 -36
  5. data/README.md +35 -4
  6. data/lib/rspec/mocks.rb +52 -13
  7. data/lib/rspec/mocks/any_instance.rb +10 -0
  8. data/lib/rspec/mocks/any_instance/chain.rb +17 -0
  9. data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +1 -1
  10. data/lib/rspec/mocks/any_instance/expectation_chain.rb +9 -6
  11. data/lib/rspec/mocks/any_instance/message_chains.rb +10 -1
  12. data/lib/rspec/mocks/any_instance/proxy.rb +112 -0
  13. data/lib/rspec/mocks/any_instance/recorder.rb +49 -18
  14. data/lib/rspec/mocks/any_instance/stub_chain.rb +5 -3
  15. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +1 -1
  16. data/lib/rspec/mocks/argument_list_matcher.rb +5 -3
  17. data/lib/rspec/mocks/argument_matchers.rb +28 -12
  18. data/lib/rspec/mocks/configuration.rb +29 -0
  19. data/lib/rspec/mocks/error_generator.rb +2 -5
  20. data/lib/rspec/mocks/example_methods.rb +122 -13
  21. data/lib/rspec/mocks/instance_method_stasher.rb +26 -2
  22. data/lib/rspec/mocks/marshal_extension.rb +41 -0
  23. data/lib/rspec/mocks/matchers/expectation_customization.rb +20 -0
  24. data/lib/rspec/mocks/matchers/receive.rb +6 -20
  25. data/lib/rspec/mocks/matchers/receive_message_chain.rb +7 -5
  26. data/lib/rspec/mocks/matchers/receive_messages.rb +1 -2
  27. data/lib/rspec/mocks/message_chain.rb +9 -9
  28. data/lib/rspec/mocks/message_expectation.rb +6 -5
  29. data/lib/rspec/mocks/method_double.rb +67 -10
  30. data/lib/rspec/mocks/method_reference.rb +1 -1
  31. data/lib/rspec/mocks/mutate_const.rb +10 -14
  32. data/lib/rspec/mocks/object_reference.rb +7 -4
  33. data/lib/rspec/mocks/proxy.rb +95 -8
  34. data/lib/rspec/mocks/space.rb +58 -9
  35. data/lib/rspec/mocks/syntax.rb +128 -210
  36. data/lib/rspec/mocks/targets.rb +6 -8
  37. data/lib/rspec/mocks/test_double.rb +16 -25
  38. data/lib/rspec/mocks/verifying_double.rb +15 -12
  39. data/lib/rspec/mocks/verifying_message_expecation.rb +3 -3
  40. data/lib/rspec/mocks/verifying_proxy.rb +23 -17
  41. data/lib/rspec/mocks/version.rb +3 -1
  42. metadata +29 -257
  43. metadata.gz.sig +0 -0
  44. data/features/README.md +0 -75
  45. data/features/Scope.md +0 -17
  46. data/features/Upgrade.md +0 -22
  47. data/features/argument_matchers/README.md +0 -27
  48. data/features/argument_matchers/explicit.feature +0 -59
  49. data/features/argument_matchers/general_matchers.feature +0 -85
  50. data/features/argument_matchers/type_matchers.feature +0 -26
  51. data/features/message_expectations/README.md +0 -75
  52. data/features/message_expectations/allow_any_instance_of.feature +0 -26
  53. data/features/message_expectations/any_instance.feature +0 -43
  54. data/features/message_expectations/block_local_expectations.feature.pending +0 -55
  55. data/features/message_expectations/call_original.feature +0 -23
  56. data/features/message_expectations/expect_message_using_expect.feature +0 -107
  57. data/features/message_expectations/expect_message_using_should_receive.feature +0 -118
  58. data/features/message_expectations/message_chains_using_expect.feature +0 -49
  59. data/features/message_expectations/receive_counts.feature +0 -209
  60. data/features/message_expectations/warn_when_expectation_is_set_on_nil.feature +0 -50
  61. data/features/method_stubs/README.md +0 -77
  62. data/features/method_stubs/allow_any_instance_of.feature +0 -136
  63. data/features/method_stubs/as_null_object.feature +0 -40
  64. data/features/method_stubs/receive_message_chain.feature +0 -51
  65. data/features/method_stubs/simple_return_value_with_allow.feature +0 -44
  66. data/features/method_stubs/simple_return_value_with_stub.feature +0 -64
  67. data/features/method_stubs/stub_implementation.feature +0 -48
  68. data/features/method_stubs/to_ary.feature +0 -51
  69. data/features/mutating_constants/README.md +0 -82
  70. data/features/mutating_constants/hiding_defined_constant.feature +0 -64
  71. data/features/mutating_constants/stub_defined_constant.feature +0 -78
  72. data/features/mutating_constants/stub_undefined_constant.feature +0 -50
  73. data/features/outside_rspec/standalone.feature +0 -33
  74. data/features/spies/spy_partial_mock_method.feature +0 -34
  75. data/features/spies/spy_pure_mock_method.feature +0 -76
  76. data/features/spies/spy_unstubbed_method.feature +0 -18
  77. data/features/step_definitions/additional_cli_steps.rb +0 -11
  78. data/features/support/env.rb +0 -22
  79. data/features/support/rubinius.rb +0 -6
  80. data/features/test_frameworks/test_unit.feature +0 -54
  81. data/features/verifying_doubles/README.md +0 -17
  82. data/features/verifying_doubles/class_doubles.feature +0 -73
  83. data/features/verifying_doubles/dynamic_classes.feature +0 -71
  84. data/features/verifying_doubles/instance_doubles.feature +0 -103
  85. data/features/verifying_doubles/object_doubles.feature +0 -65
  86. data/features/verifying_doubles/partial_doubles.feature +0 -34
  87. data/lib/rspec/mocks/extensions/marshal.rb +0 -17
  88. data/lib/rspec/mocks/framework.rb +0 -35
  89. data/lib/rspec/mocks/method_signature_verifier.rb +0 -207
  90. data/lib/rspec/mocks/ruby_features.rb +0 -24
  91. data/spec/rspec/mocks/and_call_original_spec.rb +0 -268
  92. data/spec/rspec/mocks/and_return_spec.rb +0 -23
  93. data/spec/rspec/mocks/and_yield_spec.rb +0 -126
  94. data/spec/rspec/mocks/any_instance/message_chains_spec.rb +0 -41
  95. data/spec/rspec/mocks/any_instance_spec.rb +0 -1045
  96. data/spec/rspec/mocks/array_including_matcher_spec.rb +0 -41
  97. data/spec/rspec/mocks/at_least_spec.rb +0 -123
  98. data/spec/rspec/mocks/at_most_spec.rb +0 -90
  99. data/spec/rspec/mocks/before_all_spec.rb +0 -132
  100. data/spec/rspec/mocks/block_return_value_spec.rb +0 -70
  101. data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +0 -204
  102. data/spec/rspec/mocks/configuration_spec.rb +0 -242
  103. data/spec/rspec/mocks/double_spec.rb +0 -874
  104. data/spec/rspec/mocks/example_methods_spec.rb +0 -13
  105. data/spec/rspec/mocks/extensions/marshal_spec.rb +0 -54
  106. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +0 -184
  107. data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +0 -67
  108. data/spec/rspec/mocks/hash_including_matcher_spec.rb +0 -94
  109. data/spec/rspec/mocks/instance_method_stasher_spec.rb +0 -74
  110. data/spec/rspec/mocks/matchers/have_received_spec.rb +0 -347
  111. data/spec/rspec/mocks/matchers/receive_message_chain_spec.rb +0 -198
  112. data/spec/rspec/mocks/matchers/receive_messages_spec.rb +0 -140
  113. data/spec/rspec/mocks/matchers/receive_spec.rb +0 -418
  114. data/spec/rspec/mocks/method_signature_verifier_spec.rb +0 -272
  115. data/spec/rspec/mocks/methods_spec.rb +0 -26
  116. data/spec/rspec/mocks/mock_expectation_error_spec.rb +0 -22
  117. data/spec/rspec/mocks/mock_ordering_spec.rb +0 -114
  118. data/spec/rspec/mocks/multiple_return_value_spec.rb +0 -132
  119. data/spec/rspec/mocks/mutate_const_spec.rb +0 -542
  120. data/spec/rspec/mocks/nil_expectation_warning_spec.rb +0 -52
  121. data/spec/rspec/mocks/null_object_mock_spec.rb +0 -133
  122. data/spec/rspec/mocks/once_counts_spec.rb +0 -52
  123. data/spec/rspec/mocks/options_hash_spec.rb +0 -35
  124. data/spec/rspec/mocks/order_group_spec.rb +0 -27
  125. data/spec/rspec/mocks/partial_double_spec.rb +0 -308
  126. data/spec/rspec/mocks/partial_double_using_mocks_directly_spec.rb +0 -95
  127. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +0 -145
  128. data/spec/rspec/mocks/precise_counts_spec.rb +0 -68
  129. data/spec/rspec/mocks/record_messages_spec.rb +0 -26
  130. data/spec/rspec/mocks/serialization_spec.rb +0 -90
  131. data/spec/rspec/mocks/space_spec.rb +0 -244
  132. data/spec/rspec/mocks/stash_spec.rb +0 -46
  133. data/spec/rspec/mocks/stub_chain_spec.rb +0 -168
  134. data/spec/rspec/mocks/stub_implementation_spec.rb +0 -81
  135. data/spec/rspec/mocks/stub_spec.rb +0 -327
  136. data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +0 -58
  137. data/spec/rspec/mocks/syntax_agnostic_message_matchers_spec.rb +0 -101
  138. data/spec/rspec/mocks/syntax_spec.rb +0 -19
  139. data/spec/rspec/mocks/test_double_spec.rb +0 -49
  140. data/spec/rspec/mocks/to_ary_spec.rb +0 -54
  141. data/spec/rspec/mocks/twice_counts_spec.rb +0 -66
  142. data/spec/rspec/mocks/verifying_double_spec.rb +0 -590
  143. data/spec/rspec/mocks/verifying_message_expecation_spec.rb +0 -69
  144. data/spec/rspec/mocks_spec.rb +0 -192
  145. data/spec/spec_helper.rb +0 -121
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RSpec
4
- module Mocks
5
- describe 'and_return' do
6
- let(:obj) { double('obj') }
7
-
8
- context 'when a block is passed' do
9
- it 'raises ArgumentError' do
10
- expect {
11
- obj.stub(:foo).and_return('bar') { 'baz' }
12
- }.to raise_error(ArgumentError, /implementation block/i)
13
- end
14
- end
15
-
16
- context 'when no argument is passed' do
17
- it 'raises ArgumentError' do
18
- expect { obj.stub(:foo).and_return }.to raise_error(ArgumentError)
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,126 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RSpec::Mocks::Double do
4
-
5
- let(:obj) { double }
6
-
7
- describe "#and_yield" do
8
- context 'when the method double has been constrained by `with`' do
9
- it 'uses the default stub if the provided args do not match' do
10
- obj.stub(:foo) { 15 }
11
- obj.stub(:foo).with(:yield).and_yield
12
-
13
- # should_receive is required to trigger the bug:
14
- # https://github.com/rspec/rspec-mocks/issues/127
15
- obj.should_receive(:foo)
16
-
17
- expect(obj.foo(:dont_yield)).to eq(15)
18
- end
19
- end
20
-
21
- context "with eval context as block argument" do
22
-
23
- it "evaluates the supplied block as it is read" do
24
- evaluated = false
25
- obj.stub(:method_that_accepts_a_block).and_yield do |eval_context|
26
- evaluated = true
27
- end
28
- expect(evaluated).to be_truthy
29
- end
30
-
31
- it "passes an eval context object to the supplied block" do
32
- obj.stub(:method_that_accepts_a_block).and_yield do |eval_context|
33
- expect(eval_context).not_to be_nil
34
- end
35
- end
36
-
37
- it "evaluates the block passed to the stubbed method in the context of the supplied eval context" do
38
- expected_eval_context = nil
39
- actual_eval_context = nil
40
-
41
- obj.stub(:method_that_accepts_a_block).and_yield do |eval_context|
42
- expected_eval_context = eval_context
43
- end
44
-
45
- obj.method_that_accepts_a_block do
46
- actual_eval_context = self
47
- end
48
-
49
- expect(actual_eval_context).to equal(expected_eval_context)
50
- end
51
-
52
- context "and no yielded arguments" do
53
-
54
- it "passes when expectations set on the eval context are met" do
55
- configured_eval_context = nil
56
- obj.stub(:method_that_accepts_a_block).and_yield do |eval_context|
57
- configured_eval_context = eval_context
58
- configured_eval_context.should_receive(:foo)
59
- end
60
-
61
- obj.method_that_accepts_a_block do
62
- foo
63
- end
64
-
65
- verify configured_eval_context
66
- end
67
-
68
- it "fails when expectations set on the eval context are not met" do
69
- configured_eval_context = nil
70
- obj.stub(:method_that_accepts_a_block).and_yield do |eval_context|
71
- configured_eval_context = eval_context
72
- configured_eval_context.should_receive(:foo)
73
- end
74
-
75
- obj.method_that_accepts_a_block do
76
- # foo is not called here
77
- end
78
-
79
- expect { verify configured_eval_context }.to raise_error(RSpec::Mocks::MockExpectationError)
80
- end
81
-
82
- end
83
-
84
- context "and yielded arguments" do
85
-
86
- it "passes when expectations set on the eval context and yielded arguments are met" do
87
- configured_eval_context = nil
88
- yielded_arg = Object.new
89
- obj.stub(:method_that_accepts_a_block).and_yield(yielded_arg) do |eval_context|
90
- configured_eval_context = eval_context
91
- configured_eval_context.should_receive(:foo)
92
- yielded_arg.should_receive(:bar)
93
- end
94
-
95
- obj.method_that_accepts_a_block do |obj|
96
- obj.bar
97
- foo
98
- end
99
-
100
- verify configured_eval_context
101
- verify yielded_arg
102
- end
103
-
104
- it "fails when expectations set on the eval context and yielded arguments are not met" do
105
- configured_eval_context = nil
106
- yielded_arg = Object.new
107
- obj.stub(:method_that_accepts_a_block).and_yield(yielded_arg) do |eval_context|
108
- configured_eval_context = eval_context
109
- configured_eval_context.should_receive(:foo)
110
- yielded_arg.should_receive(:bar)
111
- end
112
-
113
- obj.method_that_accepts_a_block do |obj|
114
- # obj.bar is not called here
115
- # foo is not called here
116
- end
117
-
118
- expect { verify configured_eval_context }.to raise_error(RSpec::Mocks::MockExpectationError)
119
- expect { verify yielded_arg }.to raise_error(RSpec::Mocks::MockExpectationError)
120
- end
121
-
122
- end
123
-
124
- end
125
- end
126
- end
@@ -1,41 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RSpec::Mocks::AnyInstance::MessageChains do
4
- let(:recorder) { double }
5
- let(:chains) { RSpec::Mocks::AnyInstance::MessageChains.new }
6
- let(:stub_chain) { RSpec::Mocks::AnyInstance::StubChain.new recorder }
7
- let(:expectation_chain) { RSpec::Mocks::AnyInstance::PositiveExpectationChain.new recorder }
8
-
9
- it "knows if a method does not have an expectation set on it" do
10
- chains.add(:method_name, stub_chain)
11
- expect(chains.has_expectation?(:method_name)).to be_falsey
12
- end
13
-
14
- it "knows if a method has an expectation set on it" do
15
- chains.add(:method_name, stub_chain)
16
- chains.add(:method_name, expectation_chain)
17
- expect(chains.has_expectation?(:method_name)).to be_truthy
18
- end
19
-
20
- it "can remove all stub chains" do
21
- chains.add(:method_name, stub_chain)
22
- chains.add(:method_name, expectation_chain)
23
- chains.add(:method_name, RSpec::Mocks::AnyInstance::StubChain.new(recorder))
24
-
25
- chains.remove_stub_chains_for!(:method_name)
26
- expect(chains[:method_name]).to eq([expectation_chain])
27
- end
28
-
29
- context "creating stub chains" do
30
- it "understands how to add a stub chain for a method" do
31
- chains.add(:method_name, stub_chain)
32
- expect(chains[:method_name]).to eq([stub_chain])
33
- end
34
-
35
- it "allows multiple stub chains for a method" do
36
- chains.add(:method_name, stub_chain)
37
- chains.add(:method_name, another_stub_chain = RSpec::Mocks::AnyInstance::StubChain.new(recorder))
38
- expect(chains[:method_name]).to eq([stub_chain, another_stub_chain])
39
- end
40
- end
41
- end
@@ -1,1045 +0,0 @@
1
- require 'spec_helper'
2
- require 'delegate'
3
-
4
- module RSpec
5
- module Mocks
6
- describe "#any_instance" do
7
- class CustomErrorForAnyInstanceSpec < StandardError;end
8
-
9
- let(:klass) do
10
- Class.new do
11
- def existing_method; :existing_method_return_value; end
12
- def existing_method_with_arguments(arg_one, arg_two = nil); :existing_method_with_arguments_return_value; end
13
- def another_existing_method; end
14
- private
15
- def private_method; :private_method_return_value; end
16
- end
17
- end
18
- let(:existing_method_return_value){ :existing_method_return_value }
19
-
20
- context "invocation order" do
21
- context "#stub" do
22
- it "raises an error if 'stub' follows 'with'" do
23
- expect { klass.any_instance.with("1").stub(:foo) }.to raise_error(NoMethodError)
24
- end
25
-
26
- it "raises an error if 'with' follows 'and_return'" do
27
- expect { klass.any_instance.stub(:foo).and_return(1).with("1") }.to raise_error(NoMethodError)
28
- end
29
-
30
- it "raises an error if 'with' follows 'and_raise'" do
31
- expect { klass.any_instance.stub(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError)
32
- end
33
-
34
- it "raises an error if 'with' follows 'and_yield'" do
35
- expect { klass.any_instance.stub(:foo).and_yield(1).with("1") }.to raise_error(NoMethodError)
36
- end
37
- end
38
-
39
- context "#stub_chain" do
40
- it "raises an error if 'stub_chain' follows 'and_return'" do
41
- expect { klass.any_instance.and_return("1").stub_chain(:foo, :bar) }.to raise_error(NoMethodError)
42
- end
43
- end
44
-
45
- context "#should_receive" do
46
- it "raises an error if 'should_receive' follows 'with'" do
47
- expect { klass.any_instance.with("1").should_receive(:foo) }.to raise_error(NoMethodError)
48
- end
49
-
50
- it "raises an error if 'with' follows 'and_return'" do
51
- pending "see Github issue #42"
52
- expect { klass.any_instance.should_receive(:foo).and_return(1).with("1") }.to raise_error(NoMethodError)
53
- end
54
-
55
- it "raises an error if 'with' follows 'and_raise'" do
56
- pending "see Github issue #42"
57
- expect { klass.any_instance.should_receive(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError)
58
- end
59
- end
60
- end
61
-
62
- context "with #stub" do
63
- it "does not suppress an exception when a method that doesn't exist is invoked" do
64
- klass.any_instance.stub(:foo)
65
- expect { klass.new.bar }.to raise_error(NoMethodError)
66
- end
67
-
68
- context 'multiple methods' do
69
- it "allows multiple methods to be stubbed in a single invocation" do
70
- klass.any_instance.stub(:foo => 'foo', :bar => 'bar')
71
- instance = klass.new
72
- expect(instance.foo).to eq('foo')
73
- expect(instance.bar).to eq('bar')
74
- end
75
-
76
- it "adheres to the contract of multiple method stubbing withou any instance" do
77
- expect(Object.new.stub(:foo => 'foo', :bar => 'bar')).to eq(:foo => 'foo', :bar => 'bar')
78
- expect(klass.any_instance.stub(:foo => 'foo', :bar => 'bar')).to eq(:foo => 'foo', :bar => 'bar')
79
- end
80
-
81
- context "allows a chain of methods to be stubbed using #stub_chain" do
82
- it "given symbols representing the methods" do
83
- klass.any_instance.stub_chain(:one, :two, :three).and_return(:four)
84
- expect(klass.new.one.two.three).to eq(:four)
85
- end
86
-
87
- it "given a hash as the last argument uses the value as the expected return value" do
88
- klass.any_instance.stub_chain(:one, :two, :three => :four)
89
- expect(klass.new.one.two.three).to eq(:four)
90
- end
91
-
92
- it "given a string of '.' separated method names representing the chain" do
93
- klass.any_instance.stub_chain('one.two.three').and_return(:four)
94
- expect(klass.new.one.two.three).to eq(:four)
95
- end
96
- end
97
- end
98
-
99
- context "behaves as 'every instance'" do
100
- let(:super_class) { Class.new { def foo; 'bar'; end } }
101
- let(:sub_class) { Class.new(super_class) }
102
-
103
- it "stubs every instance in the spec" do
104
- klass.any_instance.stub(:foo).and_return(result = Object.new)
105
- expect(klass.new.foo).to eq(result)
106
- expect(klass.new.foo).to eq(result)
107
- end
108
-
109
- it "stubs instance created before any_instance was called" do
110
- instance = klass.new
111
- klass.any_instance.stub(:foo).and_return(result = Object.new)
112
- expect(instance.foo).to eq(result)
113
- end
114
-
115
- it 'handles freeze and duplication correctly' do
116
- String.any_instance.stub(:any_method)
117
-
118
- foo = 'foo'.freeze
119
- expect(foo.dup.concat 'bar').to eq 'foobar'
120
- end
121
-
122
- it 'handles stubbing on super and subclasses' do
123
- super_class.any_instance.stub(:foo)
124
- sub_class.any_instance.stub(:foo).and_return('baz')
125
- expect(sub_class.new.foo).to eq('baz')
126
- end
127
-
128
- it 'handles method restoration on subclasses' do
129
- super_class.any_instance.stub(:foo)
130
- sub_class.any_instance.stub(:foo)
131
- sub_class.any_instance.unstub(:foo)
132
- expect(sub_class.new.foo).to eq("bar")
133
- end
134
- end
135
-
136
- context "with argument matching" do
137
- before do
138
- klass.any_instance.stub(:foo).with(:param_one, :param_two).and_return(:result_one)
139
- klass.any_instance.stub(:foo).with(:param_three, :param_four).and_return(:result_two)
140
- end
141
-
142
- it "returns the stubbed value when arguments match" do
143
- instance = klass.new
144
- expect(instance.foo(:param_one, :param_two)).to eq(:result_one)
145
- expect(instance.foo(:param_three, :param_four)).to eq(:result_two)
146
- end
147
-
148
- it "fails the spec with an expectation error when the arguments do not match" do
149
- expect do
150
- klass.new.foo(:param_one, :param_three)
151
- end.to(raise_error(RSpec::Mocks::MockExpectationError))
152
- end
153
- end
154
-
155
- context "with multiple stubs" do
156
- before do
157
- klass.any_instance.stub(:foo).and_return(1)
158
- klass.any_instance.stub(:bar).and_return(2)
159
- end
160
-
161
- it "stubs a method" do
162
- instance = klass.new
163
- expect(instance.foo).to eq(1)
164
- expect(instance.bar).to eq(2)
165
- end
166
-
167
- it "returns the same value for calls on different instances" do
168
- expect(klass.new.foo).to eq(klass.new.foo)
169
- expect(klass.new.bar).to eq(klass.new.bar)
170
- end
171
- end
172
-
173
- context "with #and_return" do
174
- it "stubs a method that doesn't exist" do
175
- klass.any_instance.stub(:foo).and_return(1)
176
- expect(klass.new.foo).to eq(1)
177
- end
178
-
179
- it "stubs a method that exists" do
180
- klass.any_instance.stub(:existing_method).and_return(1)
181
- expect(klass.new.existing_method).to eq(1)
182
- end
183
-
184
- it "returns the same object for calls on different instances" do
185
- return_value = Object.new
186
- klass.any_instance.stub(:foo).and_return(return_value)
187
- expect(klass.new.foo).to be(return_value)
188
- expect(klass.new.foo).to be(return_value)
189
- end
190
- end
191
-
192
- context "with #and_yield" do
193
- it "yields the value specified" do
194
- yielded_value = Object.new
195
- klass.any_instance.stub(:foo).and_yield(yielded_value)
196
- klass.new.foo{|value| expect(value).to be(yielded_value)}
197
- end
198
- end
199
-
200
- context 'with #and_call_original and competing #with' do
201
- let(:klass) { Struct.new(:a_method) }
202
-
203
- it 'can combine and_call_original, with, and_return' do
204
- allow_any_instance_of(klass).to receive(:a_method).and_call_original
205
- allow_any_instance_of(klass).to receive(:a_method).with(:arg).and_return('value')
206
-
207
- expect(klass.new('org').a_method).to eq 'org'
208
- expect(klass.new.a_method(:arg)).to eq 'value'
209
- end
210
-
211
- it 'can combine and_call_original, with, and_return (old syntax)' do
212
- klass.any_instance.stub(:a_method).and_call_original
213
- klass.any_instance.stub(:a_method).with(:arg).and_return('value')
214
-
215
- expect(klass.new('org').a_method).to eq 'org'
216
- expect(klass.new.a_method(:arg)).to eq 'value'
217
- end
218
- end
219
-
220
- context "with #and_raise" do
221
- it "stubs a method that doesn't exist" do
222
- klass.any_instance.stub(:foo).and_raise(CustomErrorForAnyInstanceSpec)
223
- expect { klass.new.foo}.to raise_error(CustomErrorForAnyInstanceSpec)
224
- end
225
-
226
- it "stubs a method that exists" do
227
- klass.any_instance.stub(:existing_method).and_raise(CustomErrorForAnyInstanceSpec)
228
- expect { klass.new.existing_method}.to raise_error(CustomErrorForAnyInstanceSpec)
229
- end
230
- end
231
-
232
- context "with a block" do
233
- it "stubs a method" do
234
- klass.any_instance.stub(:foo) { 1 }
235
- expect(klass.new.foo).to eq(1)
236
- end
237
-
238
- it "returns the same computed value for calls on different instances" do
239
- klass.any_instance.stub(:foo) { 1 + 2 }
240
- expect(klass.new.foo).to eq(klass.new.foo)
241
- end
242
- end
243
-
244
- context "when partially mocking objects" do
245
- let(:obj) { klass.new }
246
-
247
- it "resets partially mocked objects correctly" do
248
- allow_any_instance_of(klass).to receive(:existing_method).and_return("stubbed value")
249
-
250
- # Simply resetting the proxy doesn't work
251
- # what we need to have happen is
252
- # ::RSpec::Mocks.space.any_instance_recorder_for(klass).stop_all_observation!
253
- # but that is never invoked in ::
254
- expect {
255
- verify_all
256
- }.to(
257
- change { obj.existing_method }.from("stubbed value").to(:existing_method_return_value)
258
- )
259
- end
260
- end
261
-
262
- context "core ruby objects" do
263
- it "works uniformly across *everything*" do
264
- Object.any_instance.stub(:foo).and_return(1)
265
- expect(Object.new.foo).to eq(1)
266
- end
267
-
268
- it "works with the non-standard constructor []" do
269
- Array.any_instance.stub(:foo).and_return(1)
270
- expect([].foo).to eq(1)
271
- end
272
-
273
- it "works with the non-standard constructor {}" do
274
- Hash.any_instance.stub(:foo).and_return(1)
275
- expect({}.foo).to eq(1)
276
- end
277
-
278
- it "works with the non-standard constructor \"\"" do
279
- String.any_instance.stub(:foo).and_return(1)
280
- expect("".foo).to eq(1)
281
- end
282
-
283
- it "works with the non-standard constructor \'\'" do
284
- String.any_instance.stub(:foo).and_return(1)
285
- expect(''.foo).to eq(1)
286
- end
287
-
288
- it "works with the non-standard constructor module" do
289
- Module.any_instance.stub(:foo).and_return(1)
290
- module RSpec::SampleRspecTestModule;end
291
- expect(RSpec::SampleRspecTestModule.foo).to eq(1)
292
- end
293
-
294
- it "works with the non-standard constructor class" do
295
- Class.any_instance.stub(:foo).and_return(1)
296
- class RSpec::SampleRspecTestClass;end
297
- expect(RSpec::SampleRspecTestClass.foo).to eq(1)
298
- end
299
- end
300
- end
301
-
302
- context "unstub implementation" do
303
- it "replaces the stubbed method with the original method" do
304
- klass.any_instance.stub(:existing_method)
305
- klass.any_instance.unstub(:existing_method)
306
- expect(klass.new.existing_method).to eq(:existing_method_return_value)
307
- end
308
-
309
- it "removes all stubs with the supplied method name" do
310
- klass.any_instance.stub(:existing_method).with(1)
311
- klass.any_instance.stub(:existing_method).with(2)
312
- klass.any_instance.unstub(:existing_method)
313
- expect(klass.new.existing_method).to eq(:existing_method_return_value)
314
- end
315
-
316
- it "removes stubs even if they have already been invoked" do
317
- klass.any_instance.stub(:existing_method).and_return(:any_instance_value)
318
- obj = klass.new
319
- obj.existing_method
320
- klass.any_instance.unstub(:existing_method)
321
- expect(obj.existing_method).to eq(:existing_method_return_value)
322
- end
323
-
324
- it "removes stubs from sub class after invokation when super class was originally stubbed" do
325
- klass.any_instance.stub(:existing_method).and_return(:any_instance_value)
326
- obj = Class.new(klass).new
327
- expect(obj.existing_method).to eq(:any_instance_value)
328
- klass.any_instance.unstub(:existing_method)
329
- expect(obj.existing_method).to eq(:existing_method_return_value)
330
- end
331
-
332
- it "does not remove any stubs set directly on an instance" do
333
- klass.any_instance.stub(:existing_method).and_return(:any_instance_value)
334
- obj = klass.new
335
- obj.stub(:existing_method).and_return(:local_method)
336
- klass.any_instance.unstub(:existing_method)
337
- expect(obj.existing_method).to eq(:local_method)
338
- end
339
-
340
- it "does not remove any expectations with the same method name" do
341
- klass.any_instance.should_receive(:existing_method_with_arguments).with(3).and_return(:three)
342
- klass.any_instance.stub(:existing_method_with_arguments).with(1)
343
- klass.any_instance.stub(:existing_method_with_arguments).with(2)
344
- klass.any_instance.unstub(:existing_method_with_arguments)
345
- expect(klass.new.existing_method_with_arguments(3)).to eq(:three)
346
- end
347
-
348
- it "raises a MockExpectationError if the method has not been stubbed" do
349
- expect {
350
- klass.any_instance.unstub(:existing_method)
351
- }.to raise_error(RSpec::Mocks::MockExpectationError, 'The method `existing_method` was not stubbed or was already unstubbed')
352
- end
353
-
354
- it 'does not get confused about string vs symbol usage for the message' do
355
- klass.any_instance.stub(:existing_method) { :stubbed }
356
- klass.any_instance.unstub("existing_method")
357
- expect(klass.new.existing_method).to eq(:existing_method_return_value)
358
- end
359
- end
360
-
361
- context "with #should_not_receive" do
362
- it "fails if the method is called" do
363
- klass.any_instance.should_not_receive(:existing_method)
364
- expect { klass.new.existing_method }.to raise_error(RSpec::Mocks::MockExpectationError)
365
- end
366
-
367
- it "passes if no method is called" do
368
- expect { klass.any_instance.should_not_receive(:existing_method) }.to_not raise_error
369
- end
370
-
371
- it "passes if only a different method is called" do
372
- klass.any_instance.should_not_receive(:existing_method)
373
- expect { klass.new.another_existing_method }.to_not raise_error
374
- end
375
-
376
- context "with constraints" do
377
- it "fails if the method is called with the specified parameters" do
378
- klass.any_instance.should_not_receive(:existing_method_with_arguments).with(:argument_one, :argument_two)
379
- expect {
380
- klass.new.existing_method_with_arguments(:argument_one, :argument_two)
381
- }.to raise_error(RSpec::Mocks::MockExpectationError)
382
- end
383
-
384
- it "passes if the method is called with different parameters" do
385
- klass.any_instance.should_not_receive(:existing_method_with_arguments).with(:argument_one, :argument_two)
386
- expect { klass.new.existing_method_with_arguments(:argument_three, :argument_four) }.to_not raise_error
387
- end
388
- end
389
-
390
- context 'when used in combination with should_receive' do
391
- it 'passes if only the expected message is received' do
392
- klass.any_instance.should_receive(:foo)
393
- klass.any_instance.should_not_receive(:bar)
394
- klass.new.foo
395
- verify_all
396
- end
397
- end
398
-
399
- it "prevents confusing double-negative expressions involving `never`" do
400
- expect {
401
- klass.any_instance.should_not_receive(:not_expected).never
402
- }.to raise_error(/trying to negate it again/)
403
- end
404
- end
405
-
406
- context "with #should_receive" do
407
- let(:foo_expectation_error_message) { 'Exactly one instance should have received the following message(s) but didn\'t: foo' }
408
- let(:existing_method_expectation_error_message) { 'Exactly one instance should have received the following message(s) but didn\'t: existing_method' }
409
-
410
- context "with an expectation is set on a method which does not exist" do
411
- it "returns the expected value" do
412
- klass.any_instance.should_receive(:foo).and_return(1)
413
- expect(klass.new.foo(1)).to eq(1)
414
- end
415
-
416
- it "fails if an instance is created but no invocation occurs" do
417
- expect do
418
- klass.any_instance.should_receive(:foo)
419
- klass.new
420
- verify_all
421
- end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
422
- end
423
-
424
- it "fails if no instance is created" do
425
- expect do
426
- klass.any_instance.should_receive(:foo).and_return(1)
427
- verify_all
428
- end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
429
- end
430
-
431
- it "fails if no instance is created and there are multiple expectations" do
432
- expect do
433
- klass.any_instance.should_receive(:foo)
434
- klass.any_instance.should_receive(:bar)
435
- verify_all
436
- end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: bar, foo')
437
- end
438
-
439
- it "allows expectations on instances to take priority" do
440
- klass.any_instance.should_receive(:foo)
441
- klass.new.foo
442
-
443
- instance = klass.new
444
- instance.should_receive(:foo).and_return(result = Object.new)
445
- expect(instance.foo).to eq(result)
446
- end
447
-
448
- context "behaves as 'exactly one instance'" do
449
- it "passes if subsequent invocations do not receive that message" do
450
- klass.any_instance.should_receive(:foo)
451
- klass.new.foo
452
- klass.new
453
- end
454
-
455
- it "fails if the method is invoked on a second instance" do
456
- instance_one = klass.new
457
- instance_two = klass.new
458
- expect do
459
- klass.any_instance.should_receive(:foo)
460
-
461
- instance_one.foo
462
- instance_two.foo
463
- end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'foo' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}")
464
- end
465
- end
466
-
467
- context "normal expectations on the class object" do
468
- it "fail when unfulfilled" do
469
- expect do
470
- klass.any_instance.should_receive(:foo)
471
- klass.should_receive(:woot)
472
- klass.new.foo
473
- verify_all
474
- end.to(raise_error(RSpec::Mocks::MockExpectationError) do |error|
475
- expect(error.message).not_to eq(existing_method_expectation_error_message)
476
- end)
477
- end
478
-
479
-
480
- it "pass when expectations are met" do
481
- klass.any_instance.should_receive(:foo)
482
- klass.should_receive(:woot).and_return(result = Object.new)
483
- klass.new.foo
484
- expect(klass.woot).to eq(result)
485
- end
486
- end
487
- end
488
-
489
- context "with an expectation is set on a method that exists" do
490
- it "returns the expected value" do
491
- klass.any_instance.should_receive(:existing_method).and_return(1)
492
- expect(klass.new.existing_method(1)).to eq(1)
493
- end
494
-
495
- it "fails if an instance is created but no invocation occurs" do
496
- expect do
497
- klass.any_instance.should_receive(:existing_method)
498
- klass.new
499
- verify_all
500
- end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
501
- end
502
-
503
- it "fails if no instance is created" do
504
- expect do
505
- klass.any_instance.should_receive(:existing_method)
506
- verify_all
507
- end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
508
- end
509
-
510
- it "fails if no instance is created and there are multiple expectations" do
511
- expect do
512
- klass.any_instance.should_receive(:existing_method)
513
- klass.any_instance.should_receive(:another_existing_method)
514
- verify_all
515
- 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')
516
- end
517
-
518
- context "after any one instance has received a message" do
519
- it "passes if subsequent invocations do not receive that message" do
520
- klass.any_instance.should_receive(:existing_method)
521
- klass.new.existing_method
522
- klass.new
523
- end
524
-
525
- it "fails if the method is invoked on a second instance" do
526
- instance_one = klass.new
527
- instance_two = klass.new
528
- expect do
529
- klass.any_instance.should_receive(:existing_method)
530
-
531
- instance_one.existing_method
532
- instance_two.existing_method
533
- end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'existing_method' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}")
534
- end
535
- end
536
- end
537
-
538
- it 'works with a BasicObject subclass that mixes in Kernel', :if => defined?(BasicObject) do
539
- klass = Class.new(BasicObject) do
540
- include ::Kernel
541
- def foo; end
542
- end
543
-
544
- klass.any_instance.should_receive(:foo)
545
- klass.new.foo
546
- end
547
-
548
- it 'works with a SimpleDelegator subclass', :if => (RUBY_VERSION.to_f > 1.8) do
549
- klass = Class.new(SimpleDelegator) do
550
- def foo; end
551
- end
552
-
553
- klass.any_instance.should_receive(:foo)
554
- klass.new(Object.new).foo
555
- end
556
-
557
- context "with argument matching" do
558
- before do
559
- klass.any_instance.should_receive(:foo).with(:param_one, :param_two).and_return(:result_one)
560
- klass.any_instance.should_receive(:foo).with(:param_three, :param_four).and_return(:result_two)
561
- end
562
-
563
- it "returns the expected value when arguments match" do
564
- instance = klass.new
565
- expect(instance.foo(:param_one, :param_two)).to eq(:result_one)
566
- expect(instance.foo(:param_three, :param_four)).to eq(:result_two)
567
- end
568
-
569
- it "fails when the arguments match but different instances are used" do
570
- instances = Array.new(2) { klass.new }
571
- expect do
572
- expect(instances[0].foo(:param_one, :param_two)).to eq(:result_one)
573
- expect(instances[1].foo(:param_three, :param_four)).to eq(:result_two)
574
- end.to raise_error(RSpec::Mocks::MockExpectationError)
575
-
576
- # ignore the fact that should_receive expectations were not met
577
- instances.each { |instance| reset instance }
578
- end
579
-
580
- it "is not affected by the invocation of existing methods on other instances" do
581
- expect(klass.new.existing_method_with_arguments(:param_one, :param_two)).to eq(:existing_method_with_arguments_return_value)
582
- instance = klass.new
583
- expect(instance.foo(:param_one, :param_two)).to eq(:result_one)
584
- expect(instance.foo(:param_three, :param_four)).to eq(:result_two)
585
- end
586
-
587
- it "fails when arguments do not match" do
588
- instance = klass.new
589
- expect do
590
- instance.foo(:param_one, :param_three)
591
- end.to raise_error(RSpec::Mocks::MockExpectationError)
592
-
593
- # ignore the fact that should_receive expectations were not met
594
- reset instance
595
- end
596
- end
597
-
598
- context "message count" do
599
- context "the 'once' constraint" do
600
- it "passes for one invocation" do
601
- klass.any_instance.should_receive(:foo).once
602
- klass.new.foo
603
- end
604
-
605
- it "fails when no instances are declared" do
606
- expect do
607
- klass.any_instance.should_receive(:foo).once
608
- verify_all
609
- end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
610
- end
611
-
612
- it "fails when an instance is declared but there are no invocations" do
613
- expect do
614
- klass.any_instance.should_receive(:foo).once
615
- klass.new
616
- verify_all
617
- end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
618
- end
619
-
620
- it "fails for more than one invocation" do
621
- expect do
622
- klass.any_instance.should_receive(:foo).once
623
- instance = klass.new
624
- 2.times { instance.foo }
625
- verify instance
626
- end.to raise_error(RSpec::Mocks::MockExpectationError)
627
- end
628
- end
629
-
630
- context "the 'twice' constraint" do
631
- it "passes for two invocations" do
632
- klass.any_instance.should_receive(:foo).twice
633
- instance = klass.new
634
- 2.times { instance.foo }
635
- end
636
-
637
- it "fails for more than two invocations" do
638
- expect do
639
- klass.any_instance.should_receive(:foo).twice
640
- instance = klass.new
641
- 3.times { instance.foo }
642
- verify instance
643
- end.to raise_error(RSpec::Mocks::MockExpectationError)
644
- end
645
- end
646
-
647
- context "the 'exactly(n)' constraint" do
648
- it "passes for n invocations where n = 3" do
649
- klass.any_instance.should_receive(:foo).exactly(3).times
650
- instance = klass.new
651
- 3.times { instance.foo }
652
- end
653
-
654
- it "fails for n invocations where n < 3" do
655
- expect do
656
- klass.any_instance.should_receive(:foo).exactly(3).times
657
- instance = klass.new
658
- 2.times { instance.foo }
659
- verify instance
660
- end.to raise_error(RSpec::Mocks::MockExpectationError)
661
- end
662
-
663
- it "fails for n invocations where n > 3" do
664
- expect do
665
- klass.any_instance.should_receive(:foo).exactly(3).times
666
- instance = klass.new
667
- 4.times { instance.foo }
668
- verify instance
669
- end.to raise_error(RSpec::Mocks::MockExpectationError)
670
- end
671
- end
672
-
673
- context "the 'at_least(n)' constraint" do
674
- it "passes for n invocations where n = 3" do
675
- klass.any_instance.should_receive(:foo).at_least(3).times
676
- instance = klass.new
677
- 3.times { instance.foo }
678
- end
679
-
680
- it "fails for n invocations where n < 3" do
681
- expect do
682
- klass.any_instance.should_receive(:foo).at_least(3).times
683
- instance = klass.new
684
- 2.times { instance.foo }
685
- verify instance
686
- end.to raise_error(RSpec::Mocks::MockExpectationError)
687
- end
688
-
689
- it "passes for n invocations where n > 3" do
690
- klass.any_instance.should_receive(:foo).at_least(3).times
691
- instance = klass.new
692
- 4.times { instance.foo }
693
- end
694
- end
695
-
696
- context "the 'at_most(n)' constraint" do
697
- it "passes for n invocations where n = 3" do
698
- klass.any_instance.should_receive(:foo).at_most(3).times
699
- instance = klass.new
700
- 3.times { instance.foo }
701
- end
702
-
703
- it "passes for n invocations where n < 3" do
704
- klass.any_instance.should_receive(:foo).at_most(3).times
705
- instance = klass.new
706
- 2.times { instance.foo }
707
- end
708
-
709
- it "fails for n invocations where n > 3" do
710
- expect do
711
- klass.any_instance.should_receive(:foo).at_most(3).times
712
- instance = klass.new
713
- 4.times { instance.foo }
714
- verify instance
715
- end.to raise_error(RSpec::Mocks::MockExpectationError)
716
- end
717
- end
718
-
719
- context "the 'never' constraint" do
720
- it "passes for 0 invocations" do
721
- klass.any_instance.should_receive(:foo).never
722
- verify_all
723
- end
724
-
725
- it "fails on the first invocation" do
726
- expect do
727
- klass.any_instance.should_receive(:foo).never
728
- klass.new.foo
729
- end.to raise_error(RSpec::Mocks::MockExpectationError)
730
- end
731
-
732
- context "when combined with other expectations" do
733
- it "passes when the other expecations are met" do
734
- klass.any_instance.should_receive(:foo).never
735
- klass.any_instance.should_receive(:existing_method).and_return(5)
736
- expect(klass.new.existing_method).to eq(5)
737
- end
738
-
739
- it "fails when the other expecations are not met" do
740
- expect do
741
- klass.any_instance.should_receive(:foo).never
742
- klass.any_instance.should_receive(:existing_method).and_return(5)
743
- verify_all
744
- end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
745
- end
746
- end
747
- end
748
- end
749
- end
750
-
751
- context "when resetting post-verification" do
752
- let(:space) { RSpec::Mocks.space }
753
-
754
- context "existing method" do
755
- before(:each) do
756
- klass.any_instance # to force it to be tracked
757
- end
758
-
759
- context "with stubbing" do
760
- context "public methods" do
761
- before(:each) do
762
- klass.any_instance.stub(:existing_method).and_return(1)
763
- expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_truthy
764
- end
765
-
766
- it "restores the class to its original state after each example when no instance is created" do
767
- space.verify_all
768
-
769
- expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
770
- expect(klass.new.existing_method).to eq(existing_method_return_value)
771
- end
772
-
773
- it "restores the class to its original state after each example when one instance is created" do
774
- klass.new.existing_method
775
-
776
- space.verify_all
777
-
778
- expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
779
- expect(klass.new.existing_method).to eq(existing_method_return_value)
780
- end
781
-
782
- it "restores the class to its original state after each example when more than one instance is created" do
783
- klass.new.existing_method
784
- klass.new.existing_method
785
-
786
- space.verify_all
787
-
788
- expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
789
- expect(klass.new.existing_method).to eq(existing_method_return_value)
790
- end
791
- end
792
-
793
- context "private methods" do
794
- before :each do
795
- klass.any_instance.stub(:private_method).and_return(:something)
796
- space.verify_all
797
- end
798
-
799
- it "cleans up the backed up method" do
800
- expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
801
- end
802
-
803
- it "restores a stubbed private method after the spec is run" do
804
- expect(klass.private_method_defined?(:private_method)).to be_truthy
805
- end
806
-
807
- it "ensures that the restored method behaves as it originally did" do
808
- expect(klass.new.send(:private_method)).to eq(:private_method_return_value)
809
- end
810
- end
811
- end
812
-
813
- context "with expectations" do
814
- context "private methods" do
815
- before :each do
816
- klass.any_instance.should_receive(:private_method).and_return(:something)
817
- klass.new.private_method
818
- space.verify_all
819
- end
820
-
821
- it "cleans up the backed up method" do
822
- expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
823
- end
824
-
825
- it "restores a stubbed private method after the spec is run" do
826
- expect(klass.private_method_defined?(:private_method)).to be_truthy
827
- end
828
-
829
- it "ensures that the restored method behaves as it originally did" do
830
- expect(klass.new.send(:private_method)).to eq(:private_method_return_value)
831
- end
832
- end
833
-
834
- context "ensures that the subsequent specs do not see expectations set in previous specs" do
835
- context "when the instance created after the expectation is set" do
836
- it "first spec" do
837
- klass.any_instance.should_receive(:existing_method).and_return(Object.new)
838
- klass.new.existing_method
839
- end
840
-
841
- it "second spec" do
842
- expect(klass.new.existing_method).to eq(existing_method_return_value)
843
- end
844
- end
845
-
846
- context "when the instance created before the expectation is set" do
847
- before :each do
848
- @instance = klass.new
849
- end
850
-
851
- it "first spec" do
852
- klass.any_instance.should_receive(:existing_method).and_return(Object.new)
853
- @instance.existing_method
854
- end
855
-
856
- it "second spec" do
857
- expect(@instance.existing_method).to eq(existing_method_return_value)
858
- end
859
- end
860
- end
861
-
862
- it "ensures that the next spec does not see that expectation" do
863
- klass.any_instance.should_receive(:existing_method).and_return(Object.new)
864
- klass.new.existing_method
865
- space.verify_all
866
-
867
- expect(klass.new.existing_method).to eq(existing_method_return_value)
868
- end
869
- end
870
- end
871
-
872
- context "with multiple calls to any_instance in the same example" do
873
- it "does not prevent the change from being rolled back" do
874
- klass.any_instance.stub(:existing_method).and_return(false)
875
- klass.any_instance.stub(:existing_method).and_return(true)
876
-
877
- verify_all
878
- expect(klass.new).to respond_to(:existing_method)
879
- expect(klass.new.existing_method).to eq(existing_method_return_value)
880
- end
881
- end
882
-
883
- it "adds an class to the current space when #any_instance is invoked" do
884
- expect {
885
- klass.any_instance
886
- }.to change { space.any_instance_recorders.size }.by(1)
887
- end
888
-
889
- it "adds an instance to the current space when stubbed method is invoked" do
890
- klass.any_instance.stub(:foo)
891
- instance = klass.new
892
- instance.foo
893
- expect(RSpec::Mocks.space.proxies.keys).to include(instance.object_id)
894
- end
895
- end
896
-
897
- context "passing the receiver to the implementation block" do
898
- context "when configured to pass the instance" do
899
- include_context 'with isolated configuration'
900
- before(:each) do
901
- RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks = true
902
- end
903
-
904
- describe "an any instance stub" do
905
- it "passes the instance as the first arg of the implementation block" do
906
- instance = klass.new
907
-
908
- expect { |b|
909
- klass.any_instance.should_receive(:bees).with(:sup, &b)
910
- instance.bees(:sup)
911
- }.to yield_with_args(instance, :sup)
912
- end
913
-
914
- it "does not pass the instance to and_call_original" do
915
- klass = Class.new do
916
- def call(*args)
917
- args.first
918
- end
919
- end
920
- klass.any_instance.should_receive(:call).and_call_original
921
- instance = klass.new
922
- expect(instance.call(:bees)).to be :bees
923
- end
924
- end
925
-
926
- describe "an any instance expectation" do
927
- it "doesn't effect with" do
928
- instance = klass.new
929
- klass.any_instance.should_receive(:bees).with(:sup)
930
- instance.bees(:sup)
931
- end
932
-
933
- it "passes the instance as the first arg of the implementation block" do
934
- instance = klass.new
935
-
936
- expect { |b|
937
- klass.any_instance.should_receive(:bees).with(:sup, &b)
938
- instance.bees(:sup)
939
- }.to yield_with_args(instance, :sup)
940
- end
941
- end
942
- end
943
-
944
- context "when configured not to pass the instance" do
945
- include_context 'with isolated configuration'
946
- before(:each) do
947
- RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks = false
948
- end
949
-
950
- describe "an any instance stub" do
951
- it "does not pass the instance to the implementation block" do
952
- instance = klass.new
953
-
954
- expect { |b|
955
- klass.any_instance.should_receive(:bees).with(:sup, &b)
956
- instance.bees(:sup)
957
- }.to yield_with_args(:sup)
958
- end
959
-
960
- it "does not cause with to fail when the instance is passed" do
961
- instance = klass.new
962
- klass.any_instance.should_receive(:bees).with(:faces)
963
- instance.bees(:faces)
964
- end
965
- end
966
- end
967
- end
968
-
969
- context 'when used in conjunction with a `dup`' do
970
- it "doesn't cause an infinite loop" do
971
- skip "This intermittently fails on JRuby" if RUBY_PLATFORM == 'java'
972
-
973
- Object.any_instance.stub(:some_method)
974
- o = Object.new
975
- o.some_method
976
- expect { o.dup.some_method }.to_not raise_error
977
- end
978
-
979
- it "doesn't bomb if the object doesn't support `dup`" do
980
- klass = Class.new do
981
- undef_method :dup
982
- end
983
- klass.any_instance
984
- end
985
-
986
- it "doesn't fail when dup accepts parameters" do
987
- klass = Class.new do
988
- def dup(funky_option)
989
- end
990
- end
991
-
992
- klass.any_instance
993
-
994
- expect { klass.new.dup('Dup dup dup') }.to_not raise_error
995
- end
996
- end
997
-
998
- context "when directed at a method defined on a superclass" do
999
- let(:sub_klass) { Class.new(klass) }
1000
-
1001
- it "stubs the method correctly" do
1002
- klass.any_instance.stub(:existing_method).and_return("foo")
1003
- expect(sub_klass.new.existing_method).to eq "foo"
1004
- end
1005
-
1006
- it "mocks the method correctly" do
1007
- instance_one = sub_klass.new
1008
- instance_two = sub_klass.new
1009
- expect do
1010
- klass.any_instance.should_receive(:existing_method)
1011
- instance_one.existing_method
1012
- instance_two.existing_method
1013
- end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'existing_method' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}")
1014
- end
1015
- end
1016
-
1017
- context "when a class overrides Object#method" do
1018
- let(:http_request_class) { Struct.new(:method, :uri) }
1019
-
1020
- it "stubs the method correctly" do
1021
- http_request_class.any_instance.stub(:existing_method).and_return("foo")
1022
- expect(http_request_class.new.existing_method).to eq "foo"
1023
- end
1024
-
1025
- it "mocks the method correctly" do
1026
- http_request_class.any_instance.should_receive(:existing_method).and_return("foo")
1027
- expect(http_request_class.new.existing_method).to eq "foo"
1028
- end
1029
- end
1030
-
1031
- context "when used after the test has finished" do
1032
- it "restores the original behavior of a stubbed method" do
1033
- klass.any_instance.stub(:existing_method).and_return(:stubbed_return_value)
1034
-
1035
- instance = klass.new
1036
- expect(instance.existing_method).to eq :stubbed_return_value
1037
-
1038
- verify_all
1039
-
1040
- expect(instance.existing_method).to eq :existing_method_return_value
1041
- end
1042
- end
1043
- end
1044
- end
1045
- end