rspec-mocks 3.0.4 → 3.12.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +1 -1
  5. data/Changelog.md +512 -2
  6. data/{License.txt → LICENSE.md} +5 -4
  7. data/README.md +113 -30
  8. data/lib/rspec/mocks/any_instance/chain.rb +5 -3
  9. data/lib/rspec/mocks/any_instance/error_generator.rb +31 -0
  10. data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +1 -5
  11. data/lib/rspec/mocks/any_instance/expectation_chain.rb +9 -8
  12. data/lib/rspec/mocks/any_instance/message_chains.rb +7 -8
  13. data/lib/rspec/mocks/any_instance/proxy.rb +14 -5
  14. data/lib/rspec/mocks/any_instance/recorder.rb +61 -31
  15. data/lib/rspec/mocks/any_instance/stub_chain.rb +15 -11
  16. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +1 -5
  17. data/lib/rspec/mocks/any_instance.rb +1 -0
  18. data/lib/rspec/mocks/argument_list_matcher.rb +55 -10
  19. data/lib/rspec/mocks/argument_matchers.rb +88 -30
  20. data/lib/rspec/mocks/configuration.rb +61 -13
  21. data/lib/rspec/mocks/error_generator.rb +250 -107
  22. data/lib/rspec/mocks/example_methods.rb +151 -28
  23. data/lib/rspec/mocks/instance_method_stasher.rb +17 -6
  24. data/lib/rspec/mocks/matchers/have_received.rb +50 -20
  25. data/lib/rspec/mocks/matchers/receive.rb +39 -11
  26. data/lib/rspec/mocks/matchers/receive_message_chain.rb +22 -7
  27. data/lib/rspec/mocks/matchers/receive_messages.rb +12 -7
  28. data/lib/rspec/mocks/message_chain.rb +3 -7
  29. data/lib/rspec/mocks/message_expectation.rb +466 -307
  30. data/lib/rspec/mocks/method_double.rb +88 -29
  31. data/lib/rspec/mocks/method_reference.rb +85 -25
  32. data/lib/rspec/mocks/minitest_integration.rb +68 -0
  33. data/lib/rspec/mocks/mutate_const.rb +50 -109
  34. data/lib/rspec/mocks/object_reference.rb +89 -32
  35. data/lib/rspec/mocks/order_group.rb +4 -5
  36. data/lib/rspec/mocks/proxy.rb +156 -60
  37. data/lib/rspec/mocks/space.rb +52 -35
  38. data/lib/rspec/mocks/standalone.rb +1 -1
  39. data/lib/rspec/mocks/syntax.rb +26 -30
  40. data/lib/rspec/mocks/targets.rb +55 -28
  41. data/lib/rspec/mocks/test_double.rb +43 -7
  42. data/lib/rspec/mocks/verifying_double.rb +27 -33
  43. data/lib/rspec/mocks/{verifying_message_expecation.rb → verifying_message_expectation.rb} +11 -16
  44. data/lib/rspec/mocks/verifying_proxy.rb +77 -26
  45. data/lib/rspec/mocks/version.rb +1 -1
  46. data/lib/rspec/mocks.rb +8 -1
  47. data.tar.gz.sig +0 -0
  48. metadata +80 -43
  49. metadata.gz.sig +0 -0
@@ -3,7 +3,6 @@ module RSpec
3
3
  module AnyInstance
4
4
  # @private
5
5
  class StubChain < Chain
6
-
7
6
  # @private
8
7
  def expectation_fulfilled?
9
8
  true
@@ -26,20 +25,25 @@ module RSpec
26
25
  stub
27
26
  end
28
27
 
29
- def invocation_order
30
- @invocation_order ||= {
31
- :with => [nil],
28
+ InvocationOrder =
29
+ {
32
30
  :and_return => [:with, nil],
33
31
  :and_raise => [:with, nil],
34
- :and_yield => [:with, nil],
35
- :and_call_original => [:with, nil]
36
- }
32
+ :and_yield => [:with, :and_yield, nil],
33
+ :and_throw => [:with, nil],
34
+ :and_call_original => [:with, nil],
35
+ :and_wrap_original => [:with, nil]
36
+ }.freeze
37
+
38
+ EmptyInvocationOrder = {}.freeze
39
+
40
+ def invocation_order
41
+ InvocationOrder
37
42
  end
38
43
 
39
- def verify_invocation_order(rspec_method_name, *args, &block)
40
- unless invocation_order[rspec_method_name].include?(last_message)
41
- raise(NoMethodError, "Undefined method #{rspec_method_name}")
42
- end
44
+ def verify_invocation_order(rspec_method_name, *_args, &_block)
45
+ return if invocation_order.fetch(rspec_method_name, [nil]).include?(last_message)
46
+ raise NoMethodError, "Undefined method #{rspec_method_name}"
43
47
  end
44
48
  end
45
49
  end
@@ -15,11 +15,7 @@ module RSpec
15
15
  end
16
16
 
17
17
  def invocation_order
18
- @invocation_order ||= {
19
- :and_return => [nil],
20
- :and_raise => [nil],
21
- :and_yield => [nil]
22
- }
18
+ EmptyInvocationOrder
23
19
  end
24
20
  end
25
21
  end
@@ -1,5 +1,6 @@
1
1
  %w[
2
2
  any_instance/chain
3
+ any_instance/error_generator
3
4
  any_instance/stub_chain
4
5
  any_instance/stub_chain_chain
5
6
  any_instance/expect_chain_chain
@@ -44,29 +44,74 @@ module RSpec
44
44
  # @see #args_match?
45
45
  def initialize(*expected_args)
46
46
  @expected_args = expected_args
47
-
48
- @matchers = case expected_args.first
49
- when ArgumentMatchers::AnyArgsMatcher then Array
50
- when ArgumentMatchers::NoArgsMatcher then []
51
- else expected_args
52
- end
47
+ ensure_expected_args_valid!
53
48
  end
49
+ ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
54
50
 
55
51
  # @api public
56
- # @param [Array] args
52
+ # @param [Array] actual_args
57
53
  #
58
54
  # Matches each element in the `expected_args` against the element in the same
59
55
  # position of the arguments passed to `new`.
60
56
  #
61
57
  # @see #initialize
62
- def args_match?(*args)
63
- Support::FuzzyMatcher.values_match?(@matchers, args)
58
+ def args_match?(*actual_args)
59
+ expected_args = resolve_expected_args_based_on(actual_args)
60
+
61
+ return false if expected_args.size != actual_args.size
62
+
63
+ if RUBY_VERSION >= "3"
64
+ # If the expectation was set with keywords, while the actual method was called with a positional hash argument, they don't match.
65
+ # If the expectation was set without keywords, e.g., with({a: 1}), then it fine to call it with either foo(a: 1) or foo({a: 1}).
66
+ # This corresponds to Ruby semantics, as if the method was def foo(options).
67
+ if Hash === expected_args.last && Hash === actual_args.last
68
+ if !Hash.ruby2_keywords_hash?(actual_args.last) && Hash.ruby2_keywords_hash?(expected_args.last)
69
+ return false
70
+ end
71
+ end
72
+ end
73
+
74
+ Support::FuzzyMatcher.values_match?(expected_args, actual_args)
75
+ end
76
+ ruby2_keywords :args_match? if respond_to?(:ruby2_keywords, true)
77
+
78
+ # @private
79
+ # Resolves abstract arg placeholders like `no_args` and `any_args` into
80
+ # a more concrete arg list based on the provided `actual_args`.
81
+ def resolve_expected_args_based_on(actual_args)
82
+ return [] if [ArgumentMatchers::NoArgsMatcher::INSTANCE] == expected_args
83
+
84
+ any_args_index = expected_args.index { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a }
85
+ return expected_args unless any_args_index
86
+
87
+ replace_any_args_with_splat_of_anything(any_args_index, actual_args.count)
88
+ end
89
+
90
+ private
91
+
92
+ def replace_any_args_with_splat_of_anything(before_count, actual_args_count)
93
+ any_args_count = actual_args_count - expected_args.count + 1
94
+ after_count = expected_args.count - before_count - 1
95
+
96
+ any_args = 1.upto(any_args_count).map { ArgumentMatchers::AnyArgMatcher::INSTANCE }
97
+ expected_args.first(before_count) + any_args + expected_args.last(after_count)
98
+ end
99
+
100
+ def ensure_expected_args_valid!
101
+ if expected_args.count { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } > 1
102
+ raise ArgumentError, "`any_args` can only be passed to " \
103
+ "`with` once but you have passed it multiple times."
104
+ elsif expected_args.count > 1 && expected_args.any? { |a| ArgumentMatchers::NoArgsMatcher::INSTANCE == a }
105
+ raise ArgumentError, "`no_args` can only be passed as a " \
106
+ "singleton argument to `with` (i.e. `with(no_args)`), " \
107
+ "but you have passed additional arguments."
108
+ end
64
109
  end
65
110
 
66
111
  # Value that will match all argument lists.
67
112
  #
68
113
  # @private
69
- MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher.new)
114
+ MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher::INSTANCE)
70
115
  end
71
116
  end
72
117
  end
@@ -1,6 +1,10 @@
1
+ # This cannot take advantage of our relative requires, since this file is a
2
+ # dependency of `rspec/mocks/argument_list_matcher.rb`. See comment there for
3
+ # details.
4
+ require 'rspec/support/matcher_definition'
5
+
1
6
  module RSpec
2
7
  module Mocks
3
-
4
8
  # ArgumentMatchers are placeholders that you can include in message
5
9
  # expectations to match arguments against a broader check than simple
6
10
  # equality.
@@ -10,38 +14,38 @@ module RSpec
10
14
  #
11
15
  # @see ArgumentListMatcher
12
16
  module ArgumentMatchers
13
- # Matches any args at all. Supports a more explicit variation of
14
- # `expect(object).to receive(:message)`
17
+ # Acts like an arg splat, matching any number of args at any point in an arg list.
15
18
  #
16
19
  # @example
20
+ # expect(object).to receive(:message).with(1, 2, any_args)
17
21
  #
18
- # expect(object).to receive(:message).with(any_args)
22
+ # # matches any of these:
23
+ # object.message(1, 2)
24
+ # object.message(1, 2, 3)
25
+ # object.message(1, 2, 3, 4)
19
26
  def any_args
20
- AnyArgsMatcher.new
27
+ AnyArgsMatcher::INSTANCE
21
28
  end
22
29
 
23
30
  # Matches any argument at all.
24
31
  #
25
32
  # @example
26
- #
27
33
  # expect(object).to receive(:message).with(anything)
28
34
  def anything
29
- AnyArgMatcher.new
35
+ AnyArgMatcher::INSTANCE
30
36
  end
31
37
 
32
38
  # Matches no arguments.
33
39
  #
34
40
  # @example
35
- #
36
41
  # expect(object).to receive(:message).with(no_args)
37
42
  def no_args
38
- NoArgsMatcher.new
43
+ NoArgsMatcher::INSTANCE
39
44
  end
40
45
 
41
46
  # Matches if the actual argument responds to the specified messages.
42
47
  #
43
48
  # @example
44
- #
45
49
  # expect(object).to receive(:message).with(duck_type(:hello))
46
50
  # expect(object).to receive(:message).with(duck_type(:hello, :goodbye))
47
51
  def duck_type(*args)
@@ -51,17 +55,15 @@ module RSpec
51
55
  # Matches a boolean value.
52
56
  #
53
57
  # @example
54
- #
55
58
  # expect(object).to receive(:message).with(boolean())
56
59
  def boolean
57
- BooleanMatcher.new
60
+ BooleanMatcher::INSTANCE
58
61
  end
59
62
 
60
63
  # Matches a hash that includes the specified key(s) or key/value pairs.
61
64
  # Ignores any additional keys.
62
65
  #
63
66
  # @example
64
- #
65
67
  # expect(object).to receive(:message).with(hash_including(:key => val))
66
68
  # expect(object).to receive(:message).with(hash_including(:key))
67
69
  # expect(object).to receive(:message).with(hash_including(:key, :key2 => val2))
@@ -73,7 +75,6 @@ module RSpec
73
75
  # Ignores duplicates and additional values
74
76
  #
75
77
  # @example
76
- #
77
78
  # expect(object).to receive(:message).with(array_including(1,2,3))
78
79
  # expect(object).to receive(:message).with(array_including([1,2,3]))
79
80
  def array_including(*args)
@@ -84,7 +85,6 @@ module RSpec
84
85
  # Matches a hash that doesn't include the specified key(s) or key/value.
85
86
  #
86
87
  # @example
87
- #
88
88
  # expect(object).to receive(:message).with(hash_excluding(:key => val))
89
89
  # expect(object).to receive(:message).with(hash_excluding(:key))
90
90
  # expect(object).to receive(:message).with(hash_excluding(:key, :key2 => :val2))
@@ -97,7 +97,6 @@ module RSpec
97
97
  # Matches if `arg.instance_of?(klass)`
98
98
  #
99
99
  # @example
100
- #
101
100
  # expect(object).to receive(:message).with(instance_of(Thing))
102
101
  def instance_of(klass)
103
102
  InstanceOf.new(klass)
@@ -106,8 +105,8 @@ module RSpec
106
105
  alias_method :an_instance_of, :instance_of
107
106
 
108
107
  # Matches if `arg.kind_of?(klass)`
109
- # @example
110
108
  #
109
+ # @example
111
110
  # expect(object).to receive(:message).with(kind_of(Thing))
112
111
  def kind_of(klass)
113
112
  KindOf.new(klass)
@@ -117,21 +116,38 @@ module RSpec
117
116
 
118
117
  # @private
119
118
  def self.anythingize_lonely_keys(*args)
120
- hash = args.last.class == Hash ? args.delete_at(-1) : {}
121
- args.each { | arg | hash[arg] = AnyArgMatcher.new }
119
+ hash = Hash === args.last ? args.delete_at(-1) : {}
120
+ args.each { | arg | hash[arg] = AnyArgMatcher::INSTANCE }
122
121
  hash
123
122
  end
124
123
 
124
+ # Intended to be subclassed by stateless, immutable argument matchers.
125
+ # Provides a `<klass name>::INSTANCE` constant for accessing a global
126
+ # singleton instance of the matcher. There is no need to construct
127
+ # multiple instance since there is no state. It also facilities the
128
+ # special case logic we need for some of these matchers, by making it
129
+ # easy to do comparisons like: `[klass::INSTANCE] == args` rather than
130
+ # `args.count == 1 && klass === args.first`.
131
+ #
132
+ # @private
133
+ class SingletonMatcher
134
+ private_class_method :new
135
+
136
+ def self.inherited(subklass)
137
+ subklass.const_set(:INSTANCE, subklass.send(:new))
138
+ end
139
+ end
140
+
125
141
  # @private
126
- class AnyArgsMatcher
142
+ class AnyArgsMatcher < SingletonMatcher
127
143
  def description
128
- "any args"
144
+ "*(any args)"
129
145
  end
130
146
  end
131
147
 
132
148
  # @private
133
- class AnyArgMatcher
134
- def ===(other)
149
+ class AnyArgMatcher < SingletonMatcher
150
+ def ===(_other)
135
151
  true
136
152
  end
137
153
 
@@ -141,14 +157,14 @@ module RSpec
141
157
  end
142
158
 
143
159
  # @private
144
- class NoArgsMatcher
160
+ class NoArgsMatcher < SingletonMatcher
145
161
  def description
146
162
  "no args"
147
163
  end
148
164
  end
149
165
 
150
166
  # @private
151
- class BooleanMatcher
167
+ class BooleanMatcher < SingletonMatcher
152
168
  def ===(value)
153
169
  true == value || false == value
154
170
  end
@@ -166,14 +182,27 @@ module RSpec
166
182
 
167
183
  def ===(predicate, actual)
168
184
  @expected.__send__(predicate) do |k, v|
169
- actual.has_key?(k) && Support::FuzzyMatcher.values_match?(v, actual[k])
185
+ actual.key?(k) && Support::FuzzyMatcher.values_match?(v, actual[k])
170
186
  end
171
187
  rescue NoMethodError
172
188
  false
173
189
  end
174
190
 
175
191
  def description(name)
176
- "#{name}(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
192
+ "#{name}(#{formatted_expected_hash.inspect.sub(/^\{/, "").sub(/\}$/, "")})"
193
+ end
194
+
195
+ private
196
+
197
+ def formatted_expected_hash
198
+ Hash[
199
+ @expected.map do |k, v|
200
+ k = RSpec::Support.rspec_description_for_object(k)
201
+ v = RSpec::Support.rspec_description_for_object(v)
202
+
203
+ [k, v]
204
+ end
205
+ ]
177
206
  end
178
207
  end
179
208
 
@@ -206,11 +235,26 @@ module RSpec
206
235
  end
207
236
 
208
237
  def ===(actual)
209
- Set.new(actual).superset?(Set.new(@expected))
238
+ actual = actual.uniq
239
+ @expected.uniq.all? do |expected_element|
240
+ actual.any? do |actual_element|
241
+ RSpec::Support::FuzzyMatcher.values_match?(expected_element, actual_element)
242
+ end
243
+ end
244
+ rescue NoMethodError
245
+ false
210
246
  end
211
247
 
212
248
  def description
213
- "array_including(#{@expected.join(", ")})"
249
+ "array_including(#{formatted_expected_values})"
250
+ end
251
+
252
+ private
253
+
254
+ def formatted_expected_values
255
+ @expected.map do |x|
256
+ RSpec::Support.rspec_description_for_object(x)
257
+ end.join(", ")
214
258
  end
215
259
  end
216
260
 
@@ -221,7 +265,7 @@ module RSpec
221
265
  end
222
266
 
223
267
  def ===(value)
224
- @methods_to_respond_to.all? {|message| value.respond_to?(message)}
268
+ @methods_to_respond_to.all? { |message| value.respond_to?(message) }
225
269
  end
226
270
 
227
271
  def description
@@ -259,6 +303,20 @@ module RSpec
259
303
  end
260
304
  end
261
305
 
306
+ matcher_namespace = name + '::'
307
+ ::RSpec::Support.register_matcher_definition do |object|
308
+ # This is the best we have for now. We should tag all of our matchers
309
+ # with a module or something so we can test for it directly.
310
+ #
311
+ # (Note Module#parent in ActiveSupport is defined in a similar way.)
312
+ begin
313
+ object.class.name.include?(matcher_namespace)
314
+ rescue NoMethodError
315
+ # Some objects, like BasicObject, don't implemented standard
316
+ # reflection methods.
317
+ false
318
+ end
319
+ end
262
320
  end
263
321
  end
264
322
  end
@@ -2,14 +2,32 @@ module RSpec
2
2
  module Mocks
3
3
  # Provides configuration options for rspec-mocks.
4
4
  class Configuration
5
-
6
5
  def initialize
6
+ @allow_message_expectations_on_nil = nil
7
7
  @yield_receiver_to_any_instance_implementation_blocks = true
8
8
  @verify_doubled_constant_names = false
9
9
  @transfer_nested_constants = false
10
10
  @verify_partial_doubles = false
11
+ @temporarily_suppress_partial_double_verification = false
12
+ @color = false
11
13
  end
12
14
 
15
+ # Sets whether RSpec will warn, ignore, or fail a test when
16
+ # expectations are set on nil.
17
+ # By default, when this flag is not set, warning messages are issued when
18
+ # expectations are set on nil. This is to prevent false-positives and to
19
+ # catch potential bugs early on.
20
+ # When set to `true`, warning messages are suppressed.
21
+ # When set to `false`, it will raise an error.
22
+ #
23
+ # @example
24
+ # RSpec.configure do |config|
25
+ # config.mock_with :rspec do |mocks|
26
+ # mocks.allow_message_expectations_on_nil = false
27
+ # end
28
+ # end
29
+ attr_accessor :allow_message_expectations_on_nil
30
+
13
31
  def yield_receiver_to_any_instance_implementation_blocks?
14
32
  @yield_receiver_to_any_instance_implementation_blocks
15
33
  end
@@ -20,15 +38,12 @@ module RSpec
20
38
  # Defaults to `true`.
21
39
  #
22
40
  # @example
23
- #
24
41
  # RSpec.configure do |rspec|
25
42
  # rspec.mock_with :rspec do |mocks|
26
43
  # mocks.yield_receiver_to_any_instance_implementation_blocks = false
27
44
  # end
28
45
  # end
29
- def yield_receiver_to_any_instance_implementation_blocks=(arg)
30
- @yield_receiver_to_any_instance_implementation_blocks = arg
31
- end
46
+ attr_writer :yield_receiver_to_any_instance_implementation_blocks
32
47
 
33
48
  # Adds `stub` and `should_receive` to the given
34
49
  # modules or classes. This is usually only necessary
@@ -38,7 +53,6 @@ module RSpec
38
53
  # the process.
39
54
  #
40
55
  # @example
41
- #
42
56
  # RSpec.configure do |rspec|
43
57
  # rspec.mock_with :rspec do |mocks|
44
58
  # mocks.add_stub_and_should_receive_to Delegator
@@ -58,7 +72,6 @@ module RSpec
58
72
  # disable `expect` syntax.
59
73
  #
60
74
  # @example
61
- #
62
75
  # RSpec.configure do |rspec|
63
76
  # rspec.mock_with :rspec do |mocks|
64
77
  # mocks.syntax = [:expect, :should]
@@ -84,7 +97,6 @@ module RSpec
84
97
  # that are enabled.
85
98
  #
86
99
  # @example
87
- #
88
100
  # unless RSpec::Mocks.configuration.syntax.include?(:expect)
89
101
  # raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax"
90
102
  # end
@@ -105,8 +117,23 @@ module RSpec
105
117
  # constant. You probably only want to set this when running your entire
106
118
  # test suite, with all production code loaded. Setting this for an
107
119
  # isolated unit test will prevent you from being able to isolate it!
108
- def verify_doubled_constant_names=(val)
109
- @verify_doubled_constant_names = val
120
+ attr_writer :verify_doubled_constant_names
121
+
122
+ # Provides a way to perform customisations when verifying doubles.
123
+ #
124
+ # @example
125
+ # RSpec::Mocks.configuration.before_verifying_doubles do |ref|
126
+ # ref.some_method!
127
+ # end
128
+ def before_verifying_doubles(&block)
129
+ verifying_double_callbacks << block
130
+ end
131
+ alias :when_declaring_verifying_double :before_verifying_doubles
132
+
133
+ # @api private
134
+ # Returns an array of blocks to call when verifying doubles
135
+ def verifying_double_callbacks
136
+ @verifying_double_callbacks ||= []
110
137
  end
111
138
 
112
139
  def transfer_nested_constants?
@@ -115,9 +142,7 @@ module RSpec
115
142
 
116
143
  # Sets the default for the `transfer_nested_constants` option when
117
144
  # stubbing constants.
118
- def transfer_nested_constants=(val)
119
- @transfer_nested_constants = val
120
- end
145
+ attr_writer :transfer_nested_constants
121
146
 
122
147
  # When set to true, partial mocks will be verified the same as object
123
148
  # doubles. Any stubs will have their arguments checked against the original
@@ -130,6 +155,29 @@ module RSpec
130
155
  @verify_partial_doubles
131
156
  end
132
157
 
158
+ # @private
159
+ # Used to track wether we are temporarily suppressing verifying partial
160
+ # doubles with `without_partial_double_verification { ... }`
161
+ attr_accessor :temporarily_suppress_partial_double_verification
162
+
163
+ if ::RSpec.respond_to?(:configuration)
164
+ def color?
165
+ ::RSpec.configuration.color_enabled?
166
+ end
167
+ else
168
+ # Indicates whether or not diffs should be colored.
169
+ # Delegates to rspec-core's color option if rspec-core
170
+ # is loaded; otherwise you can set it here.
171
+ attr_writer :color
172
+
173
+ # Indicates whether or not diffs should be colored.
174
+ # Delegates to rspec-core's color option if rspec-core
175
+ # is loaded; otherwise you can set it here.
176
+ def color?
177
+ @color
178
+ end
179
+ end
180
+
133
181
  # Monkey-patch `Marshal.dump` to enable dumping of mocked or stubbed
134
182
  # objects. By default this will not work since RSpec mocks works by
135
183
  # adding singleton methods that cannot be serialized. This patch removes