rspec-mocks 2.11.3 → 2.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/Changelog.md +16 -0
  2. data/README.md +26 -1
  3. data/features/argument_matchers/explicit.feature +2 -2
  4. data/features/argument_matchers/general_matchers.feature +4 -4
  5. data/features/argument_matchers/type_matchers.feature +1 -1
  6. data/features/message_expectations/README.md +4 -0
  7. data/features/message_expectations/any_instance.feature +1 -1
  8. data/features/message_expectations/call_original.feature +24 -0
  9. data/features/message_expectations/expect_message.feature +5 -5
  10. data/features/message_expectations/receive_counts.feature +7 -7
  11. data/features/message_expectations/warn_when_expectation_is_set_on_nil.feature +3 -3
  12. data/features/method_stubs/any_instance.feature +6 -7
  13. data/features/method_stubs/as_null_object.feature +1 -1
  14. data/features/method_stubs/simple_return_value.feature +2 -2
  15. data/features/method_stubs/stub_chain.feature +1 -1
  16. data/features/method_stubs/stub_implementation.feature +1 -1
  17. data/features/method_stubs/to_ary.feature +1 -1
  18. data/features/{stubbing_constants → mutating_constants}/README.md +21 -1
  19. data/features/mutating_constants/hiding_defined_constant.feature +64 -0
  20. data/features/{stubbing_constants → mutating_constants}/stub_defined_constant.feature +0 -0
  21. data/features/{stubbing_constants → mutating_constants}/stub_undefined_constant.feature +0 -0
  22. data/features/outside_rspec/configuration.feature +3 -3
  23. data/features/outside_rspec/standalone.feature +6 -5
  24. data/lib/rspec/mocks.rb +17 -1
  25. data/lib/rspec/mocks/any_instance.rb +12 -12
  26. data/lib/rspec/mocks/configuration.rb +28 -0
  27. data/lib/rspec/mocks/error_generator.rb +6 -0
  28. data/lib/rspec/mocks/example_methods.rb +34 -9
  29. data/lib/rspec/mocks/framework.rb +3 -2
  30. data/lib/rspec/mocks/instance_method_stasher.rb +70 -0
  31. data/lib/rspec/mocks/message_expectation.rb +49 -29
  32. data/lib/rspec/mocks/method_double.rb +84 -7
  33. data/lib/rspec/mocks/{stub_const.rb → mutate_const.rb} +117 -40
  34. data/lib/rspec/mocks/proxy.rb +16 -5
  35. data/lib/rspec/mocks/version.rb +1 -1
  36. data/spec/rspec/mocks/and_call_original_spec.rb +162 -0
  37. data/spec/rspec/mocks/any_instance_spec.rb +18 -7
  38. data/spec/rspec/mocks/configuration_spec.rb +26 -0
  39. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +9 -10
  40. data/spec/rspec/mocks/instance_method_stasher_spec.rb +58 -0
  41. data/spec/rspec/mocks/mock_spec.rb +35 -35
  42. data/spec/rspec/mocks/{stub_const_spec.rb → mutate_const_spec.rb} +142 -13
  43. data/spec/rspec/mocks/null_object_mock_spec.rb +3 -2
  44. data/spec/rspec/mocks/partial_mock_spec.rb +102 -77
  45. data/spec/rspec/mocks/serialization_spec.rb +1 -2
  46. data/spec/rspec/mocks/stub_implementation_spec.rb +6 -6
  47. data/spec/rspec/mocks_spec.rb +7 -0
  48. data/spec/spec_helper.rb +11 -0
  49. metadata +79 -80
  50. data/lib/rspec/mocks/stashed_instance_method.rb +0 -60
  51. data/spec/rspec/mocks/stashed_instance_method_spec.rb +0 -53
@@ -0,0 +1,64 @@
1
+ Feature: Hide Defined Constant
2
+
3
+ Use `hide_const` to remove a constant for the duration of a test.
4
+
5
+ Scenario: Hide top-level constant
6
+ Given a file named "hide_const_spec.rb" with:
7
+ """ruby
8
+ FOO = 7
9
+
10
+ describe "hiding FOO" do
11
+ it "can hide FOO" do
12
+ hide_const("FOO")
13
+ expect { FOO }.to raise_error(NameError)
14
+ end
15
+
16
+ it "restores the hidden constant when the example completes" do
17
+ FOO.should eq(7)
18
+ end
19
+ end
20
+ """
21
+ When I run `rspec hide_const_spec.rb`
22
+ Then the examples should all pass
23
+
24
+ Scenario: Hide nested constant
25
+ Given a file named "hide_const_spec.rb" with:
26
+ """ruby
27
+ module MyGem
28
+ class SomeClass
29
+ FOO = 7
30
+ end
31
+ end
32
+
33
+ module MyGem
34
+ describe SomeClass do
35
+ it "hides the nested constant when it is fully qualified" do
36
+ hide_const("MyGem::SomeClass::FOO")
37
+ expect { SomeClass::FOO }.to raise_error(NameError)
38
+ end
39
+
40
+ it "restores the hidden constant when the example completes" do
41
+ MyGem::SomeClass::FOO.should eq(7)
42
+ end
43
+ end
44
+ end
45
+ """
46
+ When I run `rspec hide_const_spec.rb`
47
+ Then the examples should all pass
48
+
49
+ Scenario: Hiding undefined constant
50
+ Given a file named "hide_const_spec.rb" with:
51
+ """
52
+ describe "hiding UNDEFINED_CONSTANT" do
53
+ it "has no effect" do
54
+ hide_const("UNDEFINED_CONSTANT")
55
+ expect { UNDEFINED_CONSTANT }.to raise_error(NameError)
56
+ end
57
+
58
+ it "is still undefined after the example completes" do
59
+ expect { UNDEFINED_CONSTANT }.to raise_error(NameError)
60
+ end
61
+ end
62
+ """
63
+ When I run `rspec hide_const_spec.rb`
64
+ Then the examples should all pass
@@ -25,7 +25,7 @@ Feature: configure any test framework to use rspec-mocks
25
25
 
26
26
  Scenario: RSpec::Mocks::setup(object) adds double, mock, and stub methods to the submitted object
27
27
  Given a file named "foo.rb" with:
28
- """
28
+ """ruby
29
29
  require 'rspec/mocks'
30
30
 
31
31
  class CodeExample
@@ -48,7 +48,7 @@ Feature: configure any test framework to use rspec-mocks
48
48
 
49
49
  Scenario: RSpec::Mocks::setup(anything) adds methods to Object
50
50
  Given a file named "foo.rb" with:
51
- """
51
+ """ruby
52
52
  require 'rspec/mocks'
53
53
 
54
54
  RSpec::Mocks::setup(Object.new)
@@ -66,7 +66,7 @@ Feature: configure any test framework to use rspec-mocks
66
66
 
67
67
  Scenario: require "rspec/mocks" does not add methods to Object
68
68
  Given a file named "foo.rb" with:
69
- """
69
+ """ruby
70
70
  require 'rspec/mocks'
71
71
 
72
72
  obj = Object.new
@@ -6,7 +6,7 @@ Feature: standalone
6
6
 
7
7
  Scenario: method stub outside rspec
8
8
  Given a file named "example.rb" with:
9
- """
9
+ """ruby
10
10
  require "rspec/mocks/standalone"
11
11
 
12
12
  greeter = double("greeter")
@@ -18,7 +18,7 @@ Feature: standalone
18
18
 
19
19
  Scenario: message expectation outside rspec
20
20
  Given a file named "example.rb" with:
21
- """
21
+ """ruby
22
22
  require "rspec/mocks/standalone"
23
23
 
24
24
  greeter = double("greeter")
@@ -27,6 +27,7 @@ Feature: standalone
27
27
  RSpec::Mocks.verify
28
28
  """
29
29
  When I run `ruby example.rb`
30
- Then the output should contain "say_hi(any args) (RSpec::Mocks::MockExpectationError)"
31
- Then the output should contain "expected: 1 time"
32
- Then the output should contain "received: 0 times"
30
+ Then the output should contain "RSpec::Mocks::MockExpectationError"
31
+ And the output should contain "say_hi(any args)"
32
+ And the output should contain "expected: 1 time"
33
+ And the output should contain "received: 0 times"
@@ -23,10 +23,14 @@ module RSpec
23
23
  space.reset_all
24
24
  end
25
25
 
26
+ def configuration
27
+ @configuration ||= Configuration.new
28
+ end
29
+
26
30
  private
27
31
 
28
32
  def add_extensions
29
- Object.class_eval { include RSpec::Mocks::Methods }
33
+ method_host.class_eval { include RSpec::Mocks::Methods }
30
34
  Class.class_eval { include RSpec::Mocks::AnyInstance }
31
35
  $_rspec_mocks_extensions_added = true
32
36
  end
@@ -34,6 +38,18 @@ module RSpec
34
38
  def extensions_added?
35
39
  defined?($_rspec_mocks_extensions_added)
36
40
  end
41
+
42
+ def method_host
43
+ # On 1.8.7, Object.ancestors.last == Kernel but
44
+ # things blow up if we include `RSpec::Mocks::Methods`
45
+ # into Kernel...not sure why.
46
+ return Object unless defined?(::BasicObject)
47
+
48
+ # MacRuby has BasicObject but it's not the root class.
49
+ return Object unless Object.ancestors.last == ::BasicObject
50
+
51
+ ::BasicObject
52
+ end
37
53
  end
38
54
  end
39
55
  end
@@ -30,7 +30,7 @@ module RSpec
30
30
  modify_dup_to_remove_mock_proxy_when_invoked
31
31
  __recorder
32
32
  end
33
-
33
+
34
34
  # @private
35
35
  def rspec_verify
36
36
  __recorder.verify
@@ -40,36 +40,36 @@ module RSpec
40
40
  restore_dup
41
41
  @__recorder = nil
42
42
  end
43
-
43
+
44
44
  # @private
45
45
  def rspec_reset
46
46
  restore_dup
47
47
  __mock_proxy.reset
48
48
  end
49
-
49
+
50
50
  # @private
51
51
  def __recorder
52
52
  @__recorder ||= AnyInstance::Recorder.new(self)
53
53
  end
54
-
54
+
55
55
  private
56
56
  def modify_dup_to_remove_mock_proxy_when_invoked
57
- if self.method_defined?(:dup) and !self.method_defined?(:__rspec_original_dup)
58
- self.class_eval do
59
- def __rspec_dup
57
+ if method_defined?(:dup) and !method_defined?(:__rspec_original_dup)
58
+ class_eval do
59
+ def __rspec_dup(*arguments, &block)
60
60
  __remove_mock_proxy
61
- __rspec_original_dup
61
+ __rspec_original_dup(*arguments, &block)
62
62
  end
63
-
63
+
64
64
  alias_method :__rspec_original_dup, :dup
65
65
  alias_method :dup, :__rspec_dup
66
66
  end
67
67
  end
68
68
  end
69
-
69
+
70
70
  def restore_dup
71
- if self.method_defined?(:__rspec_original_dup)
72
- self.class_eval do
71
+ if method_defined?(:__rspec_original_dup)
72
+ class_eval do
73
73
  alias_method :dup, :__rspec_original_dup
74
74
  remove_method :__rspec_original_dup
75
75
  remove_method :__rspec_dup
@@ -0,0 +1,28 @@
1
+ module RSpec
2
+ module Mocks
3
+ # Provides configuration options for rspec-mocks.
4
+ class Configuration
5
+ # Adds `stub` and `should_receive` to the given
6
+ # modules or classes. This is usually only necessary
7
+ # if you application uses some proxy classes that
8
+ # "strip themselves down" to a bare minimum set of
9
+ # methods and remove `stub` and `should_receive` in
10
+ # the process.
11
+ #
12
+ # @example
13
+ #
14
+ # RSpec.configure do |rspec|
15
+ # rspec.mock_with :rspec do |mocks|
16
+ # mocks.add_stub_and_should_receive_to Delegator
17
+ # end
18
+ # end
19
+ #
20
+ def add_stub_and_should_receive_to(*modules)
21
+ modules.each do |mod|
22
+ mod.__send__(:include, RSpec::Mocks::Methods)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -66,6 +66,12 @@ module RSpec
66
66
  __raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}"
67
67
  end
68
68
 
69
+ # @private
70
+ def raise_only_valid_on_a_partial_mock(method)
71
+ __raise "#{intro} is a pure mock object. `#{method}` is only " +
72
+ "available on a partial mock object."
73
+ end
74
+
69
75
  private
70
76
 
71
77
  def intro
@@ -3,12 +3,18 @@ module RSpec
3
3
  module ExampleMethods
4
4
  include RSpec::Mocks::ArgumentMatchers
5
5
 
6
- # Creates an instance of RSpec::Mocks::Mock.
6
+ # @overload double()
7
+ # @overload double(name)
8
+ # @overload double(stubs)
9
+ # @overload double(name, stubs)
10
+ # @param name [String/Symbol] (optional) used in
11
+ # clarify intent
12
+ # @param stubs (Hash) (optional) hash of method/return-value pairs
13
+ # @return (Mock)
7
14
  #
8
- # `name` is used for failure reporting, so you should use the role that
9
- # the mock is playing in the example.
10
- #
11
- # Use `stubs` to declare one or more method stubs in one statement.
15
+ # Constructs an instance of [RSpec::Mocks::Mock](RSpec::Mocks::Mock) configured
16
+ # with an optional name, used for reporting in failure messages, and an optional
17
+ # hash of method/return-value pairs.
12
18
  #
13
19
  # @example
14
20
  #
@@ -18,16 +24,19 @@ module RSpec
18
24
  # card = double("card", :suit => "Spades", :rank => "A")
19
25
  # card.suit #=> "Spades"
20
26
  # card.rank #=> "A"
27
+ #
28
+ # @see #mock
29
+ # @see #stub
21
30
  def double(*args)
22
31
  declare_double('Double', *args)
23
32
  end
24
33
 
25
- # Just like double
34
+ # Effectively an alias for [double](#double-instance_method).
26
35
  def mock(*args)
27
36
  declare_double('Mock', *args)
28
37
  end
29
38
 
30
- # Just like double
39
+ # Effectively an alias for [double](#double-instance_method).
31
40
  def stub(*args)
32
41
  declare_double('Stub', *args)
33
42
  end
@@ -79,11 +88,27 @@ module RSpec
79
88
  # CardDeck::SUITS # => our suits array
80
89
  # CardDeck::NUM_CARDS # => uninitialized constant error
81
90
  def stub_const(constant_name, value, options = {})
82
- ConstantStubber.stub(constant_name, value, options)
91
+ ConstantMutator.stub(constant_name, value, options)
92
+ end
93
+
94
+ # Hides the named constant with the given value. The constant will be
95
+ # undefined for the duration of the test.
96
+ #
97
+ # Like method stubs, the constant will be restored to its original value
98
+ # when the example completes.
99
+ #
100
+ # @param constant_name [String] The fully qualified name of the constant.
101
+ # The current constant scoping at the point of call is not considered.
102
+ #
103
+ # @example
104
+ #
105
+ # hide_const("MyClass") # => MyClass is now an undefined constant
106
+ def hide_const(constant_name)
107
+ ConstantMutator.hide(constant_name)
83
108
  end
84
109
 
85
110
  private
86
-
111
+
87
112
  def declare_double(declared_as, *args)
88
113
  args << {} unless Hash === args.last
89
114
  args.last[:__declared_as] = declared_as
@@ -2,8 +2,9 @@
2
2
  # supports wrapping rspec's mocking functionality without invading every
3
3
  # object in the system.
4
4
 
5
+ require 'rspec/mocks/configuration'
5
6
  require 'rspec/mocks/extensions/instance_exec'
6
- require 'rspec/mocks/stashed_instance_method'
7
+ require 'rspec/mocks/instance_method_stasher'
7
8
  require 'rspec/mocks/method_double'
8
9
  require 'rspec/mocks/methods'
9
10
  require 'rspec/mocks/argument_matchers'
@@ -18,4 +19,4 @@ require 'rspec/mocks/error_generator'
18
19
  require 'rspec/mocks/space'
19
20
  require 'rspec/mocks/serialization'
20
21
  require 'rspec/mocks/any_instance'
21
- require 'rspec/mocks/stub_const'
22
+ require 'rspec/mocks/mutate_const'
@@ -0,0 +1,70 @@
1
+ module RSpec
2
+ module Mocks
3
+ # @private
4
+ class InstanceMethodStasher
5
+ def initialize(klass, method)
6
+ @klass = klass
7
+ @method = method
8
+
9
+ @method_is_stashed = false
10
+ end
11
+
12
+ # @private
13
+ def method_is_stashed?
14
+ @method_is_stashed
15
+ end
16
+
17
+ # @private
18
+ def stash
19
+ return if !method_defined_directly_on_klass? || @method_is_stashed
20
+
21
+ @klass.__send__(:alias_method, stashed_method_name, @method)
22
+ @method_is_stashed = true
23
+ end
24
+
25
+ private
26
+
27
+ # @private
28
+ def method_defined_directly_on_klass?
29
+ method_defined_on_klass? && method_owned_by_klass?
30
+ end
31
+
32
+ # @private
33
+ def method_defined_on_klass?
34
+ @klass.method_defined?(@method) || @klass.private_method_defined?(@method)
35
+ end
36
+
37
+ if ::UnboundMethod.method_defined?(:owner)
38
+ # @private
39
+ def method_owned_by_klass?
40
+ @klass.instance_method(@method).owner == @klass
41
+ end
42
+ else
43
+ # @private
44
+ def method_owned_by_klass?
45
+ # On 1.8.6, which does not support Method#owner, we have no choice but
46
+ # to assume it's defined on the klass even if it may be defined on
47
+ # a superclass.
48
+ true
49
+ end
50
+ end
51
+
52
+ public
53
+
54
+ # @private
55
+ def stashed_method_name
56
+ "obfuscated_by_rspec_mocks__#{@method}"
57
+ end
58
+
59
+ # @private
60
+ def restore
61
+ return unless @method_is_stashed
62
+
63
+ @klass.__send__(:alias_method, @method, stashed_method_name)
64
+ @klass.__send__(:remove_method, stashed_method_name)
65
+ @method_is_stashed = false
66
+ end
67
+ end
68
+ end
69
+ end
70
+
@@ -9,11 +9,13 @@ module RSpec
9
9
  protected :expected_received_count=, :expected_from=, :error_generator, :error_generator=
10
10
 
11
11
  # @private
12
- def initialize(error_generator, expectation_ordering, expected_from, message, expected_received_count=1, opts={}, &implementation)
12
+ def initialize(error_generator, expectation_ordering, expected_from, method_double,
13
+ expected_received_count=1, opts={}, &implementation)
13
14
  @error_generator = error_generator
14
15
  @error_generator.opts = opts
15
16
  @expected_from = expected_from
16
- @message = message
17
+ @method_double = method_double
18
+ @message = @method_double.method_name
17
19
  @actual_received_count = 0
18
20
  @expected_received_count = expected_received_count
19
21
  @argument_list_matcher = ArgumentListMatcher.new(ArgumentMatchers::AnyArgsMatcher.new)
@@ -97,8 +99,28 @@ module RSpec
97
99
  @implementation = implementation || build_implementation(values)
98
100
  end
99
101
 
102
+ # Tells the object to delegate to the original unmodified method
103
+ # when it receives the message.
104
+ #
105
+ # @note This is only available on partial mock objects.
106
+ #
107
+ # @example
108
+ #
109
+ # counter.should_receive(:increment).and_call_original
110
+ # original_count = counter.count
111
+ # counter.increment
112
+ # expect(counter.count).to eq(original_count + 1)
113
+ def and_call_original
114
+ if @method_double.object.is_a?(RSpec::Mocks::TestDouble)
115
+ @error_generator.raise_only_valid_on_a_partial_mock(:and_call_original)
116
+ else
117
+ self.implementation = @method_double.original_method
118
+ end
119
+ end
120
+
100
121
  # @overload and_raise
101
122
  # @overload and_raise(ExceptionClass)
123
+ # @overload and_raise(ExceptionClass, message)
102
124
  # @overload and_raise(exception_instance)
103
125
  #
104
126
  # Tells the object to raise an exception when the message is received.
@@ -106,17 +128,23 @@ module RSpec
106
128
  # @note
107
129
  #
108
130
  # When you pass an exception class, the MessageExpectation will raise
109
- # an instance of it, creating it with `new`. If the exception class
110
- # initializer requires any parameters, you must pass in an instance and
111
- # not the class.
131
+ # an instance of it, creating it with `exception` and passing `message`
132
+ # if specified. If the exception class initializer requires more than
133
+ # one parameters, you must pass in an instance and not the class,
134
+ # otherwise this method will raise an ArgumentError exception.
112
135
  #
113
136
  # @example
114
137
  #
115
138
  # car.stub(:go).and_raise
116
139
  # car.stub(:go).and_raise(OutOfGas)
140
+ # car.stub(:go).and_raise(OutOfGas, "At least 2 oz of gas needed to drive")
117
141
  # car.stub(:go).and_raise(OutOfGas.new(2, :oz))
118
- def and_raise(exception=RuntimeError)
119
- @exception_to_raise = exception
142
+ def and_raise(exception = RuntimeError, message = nil)
143
+ if exception.respond_to?(:exception)
144
+ @exception_to_raise = message ? exception.exception(message) : exception.exception
145
+ else
146
+ @exception_to_raise = exception
147
+ end
120
148
  end
121
149
 
122
150
  # @overload and_throw(symbol)
@@ -167,7 +195,7 @@ module RSpec
167
195
  @order_group.handle_order_constraint self
168
196
 
169
197
  begin
170
- raise_exception unless @exception_to_raise.nil?
198
+ raise(@exception_to_raise) unless @exception_to_raise.nil?
171
199
  Kernel::throw(*@args_to_throw) unless @args_to_throw.empty?
172
200
 
173
201
  default_return_val = call_with_yield(&block) if !@args_to_yield.empty? || @eval_context
@@ -184,19 +212,6 @@ module RSpec
184
212
  end
185
213
  end
186
214
 
187
- # @private
188
- def raise_exception
189
- if !@exception_to_raise.respond_to?(:instance_method) ||
190
- @exception_to_raise.instance_method(:initialize).arity <= 0
191
- raise(@exception_to_raise)
192
- else
193
- raise ArgumentError.new(<<-MESSAGE)
194
- 'and_raise' can only accept an Exception class if an instance can be constructed with no arguments.
195
- #{@exception_to_raise.to_s}'s initialize method requires #{@exception_to_raise.instance_method(:initialize).arity} arguments, so you have to supply an instance instead.
196
- MESSAGE
197
- end
198
- end
199
-
200
215
  # @private
201
216
  def called_max_times?
202
217
  @expected_received_count != :any &&
@@ -301,7 +316,7 @@ MESSAGE
301
316
  #
302
317
  # @example
303
318
  #
304
- # dealer.should_recieve(:deal_card).exactly(10).times
319
+ # dealer.should_receive(:deal_card).exactly(10).times
305
320
  def exactly(n, &block)
306
321
  @implementation = block if block
307
322
  set_expected_received_count :exactly, n
@@ -313,7 +328,7 @@ MESSAGE
313
328
  #
314
329
  # @example
315
330
  #
316
- # dealer.should_recieve(:deal_card).at_least(9).times
331
+ # dealer.should_receive(:deal_card).at_least(9).times
317
332
  def at_least(n, &block)
318
333
  @implementation = block if block
319
334
  set_expected_received_count :at_least, n
@@ -325,7 +340,7 @@ MESSAGE
325
340
  #
326
341
  # @example
327
342
  #
328
- # dealer.should_recieve(:deal_card).at_most(10).times
343
+ # dealer.should_receive(:deal_card).at_most(10).times
329
344
  def at_most(n, &block)
330
345
  @implementation = block if block
331
346
  set_expected_received_count :at_most, n
@@ -336,9 +351,9 @@ MESSAGE
336
351
  #
337
352
  # @example
338
353
  #
339
- # dealer.should_recieve(:deal_card).exactly(10).times
340
- # dealer.should_recieve(:deal_card).at_least(10).times
341
- # dealer.should_recieve(:deal_card).at_most(10).times
354
+ # dealer.should_receive(:deal_card).exactly(10).times
355
+ # dealer.should_receive(:deal_card).at_least(10).times
356
+ # dealer.should_receive(:deal_card).at_most(10).times
342
357
  def times(&block)
343
358
  @implementation = block if block
344
359
  self
@@ -471,12 +486,17 @@ MESSAGE
471
486
  # @private
472
487
  class NegativeMessageExpectation < MessageExpectation
473
488
  # @private
474
- def initialize(error_generator, expectation_ordering, expected_from, message, &implementation)
475
- super(error_generator, expectation_ordering, expected_from, message, 0, {}, &implementation)
489
+ def initialize(error_generator, expectation_ordering, expected_from, method_double, &implementation)
490
+ super(error_generator, expectation_ordering, expected_from, method_double, 0, {}, &implementation)
476
491
  end
477
492
 
478
493
  def and_return(*)
479
494
  # no-op
495
+ # @deprecated and_return is not supported with negative message expectations.
496
+ RSpec.warn_deprecation <<-MSG
497
+
498
+ DEPRECATION: `and_return` with `should_not_receive` is deprecated. Called from #{caller(0)[1]}
499
+ MSG
480
500
  end
481
501
 
482
502
  # @private