rspec-mocks 2.11.3 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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