rr 0.4.10 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +14 -0
- data/README.rdoc +67 -13
- data/Rakefile +1 -1
- data/lib/rr.rb +29 -9
- data/lib/rr/adapters/rr_methods.rb +38 -158
- data/lib/rr/double.rb +46 -41
- data/lib/rr/double_definitions/child_double_definition_creator.rb +23 -0
- data/lib/rr/double_definitions/double_definition.rb +212 -0
- data/lib/rr/double_definitions/double_definition_creator.rb +153 -0
- data/lib/rr/double_definitions/double_definition_creator_proxy.rb +25 -0
- data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +15 -0
- data/lib/rr/double_definitions/strategies/implementation/proxy.rb +62 -0
- data/lib/rr/double_definitions/strategies/implementation/reimplementation.rb +14 -0
- data/lib/rr/double_definitions/strategies/scope/instance.rb +15 -0
- data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +43 -0
- data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +15 -0
- data/lib/rr/double_definitions/strategies/strategy.rb +70 -0
- data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +34 -0
- data/lib/rr/double_definitions/strategies/verification/mock.rb +44 -0
- data/lib/rr/double_definitions/strategies/verification/stub.rb +45 -0
- data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +15 -0
- data/lib/rr/double_injection.rb +21 -15
- data/lib/rr/expectations/argument_equality_expectation.rb +2 -1
- data/lib/rr/space.rb +23 -22
- data/lib/rr/wildcard_matchers/hash_including.rb +29 -0
- data/lib/rr/wildcard_matchers/satisfy.rb +26 -0
- data/spec/high_level_spec.rb +111 -64
- data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +1 -1
- data/spec/rr/adapters/rr_methods_creator_spec.rb +99 -315
- data/spec/rr/adapters/rr_methods_space_spec.rb +90 -109
- data/spec/rr/adapters/rr_methods_spec_helper.rb +1 -1
- data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +1 -1
- data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +103 -0
- data/spec/rr/double_definitions/double_definition_creator_proxy_spec.rb +83 -0
- data/spec/rr/double_definitions/double_definition_creator_spec.rb +495 -0
- data/spec/rr/double_definitions/double_definition_spec.rb +1116 -0
- data/spec/rr/double_injection/double_injection_bind_spec.rb +111 -0
- data/spec/rr/double_injection/double_injection_dispatching_spec.rb +245 -0
- data/spec/rr/{double → double_injection}/double_injection_has_original_method_spec.rb +9 -9
- data/spec/rr/double_injection/double_injection_reset_spec.rb +90 -0
- data/spec/rr/double_injection/double_injection_spec.rb +77 -0
- data/spec/rr/double_injection/double_injection_verify_spec.rb +29 -0
- data/spec/rr/double_spec.rb +156 -136
- data/spec/rr/errors/rr_error_spec.rb +1 -1
- data/spec/rr/expectations/any_argument_expectation_spec.rb +1 -1
- data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +6 -30
- data/spec/rr/expectations/argument_equality_expectation_spec.rb +35 -18
- data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +22 -41
- data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
- data/spec/rr/expectations/hash_including_spec.rb +17 -0
- data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +59 -0
- data/spec/rr/expectations/satisfy_spec.rb +14 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +30 -28
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +55 -54
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +49 -48
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +9 -7
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +77 -76
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +58 -57
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +59 -58
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +25 -24
- data/spec/rr/rspec/rspec_adapter_spec.rb +12 -11
- data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +10 -8
- data/spec/rr/rspec/rspec_usage_spec.rb +1 -1
- data/spec/rr/space/hash_with_object_id_key_spec.rb +1 -1
- data/spec/rr/space/space_spec.rb +330 -192
- data/spec/rr/test_unit/test_helper.rb +1 -2
- data/spec/rr/test_unit/test_unit_backtrace_test.rb +1 -2
- data/spec/rr/test_unit/test_unit_integration_test.rb +1 -2
- data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/integer_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/proc_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/range_matcher_spec.rb +1 -1
- data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +1 -1
- data/spec/rr/wildcard_matchers/anything_spec.rb +24 -0
- data/spec/rr/wildcard_matchers/boolean_spec.rb +36 -0
- data/spec/rr/wildcard_matchers/duck_type_spec.rb +52 -0
- data/spec/rr/wildcard_matchers/is_a_spec.rb +32 -0
- data/spec/rr/wildcard_matchers/numeric_spec.rb +32 -0
- data/spec/rr/wildcard_matchers/range_spec.rb +35 -0
- data/spec/rr/wildcard_matchers/regexp_spec.rb +43 -0
- data/spec/rr_spec.rb +28 -0
- data/spec/spec_helper.rb +84 -0
- metadata +43 -29
- data/lib/rr/double_creator.rb +0 -271
- data/lib/rr/double_definition.rb +0 -179
- data/lib/rr/double_definition_builder.rb +0 -44
- data/lib/rr/double_definition_creator.rb +0 -156
- data/lib/rr/double_definition_creator_proxy.rb +0 -20
- data/spec/rr/double/double_injection_bind_spec.rb +0 -105
- data/spec/rr/double/double_injection_dispatching_spec.rb +0 -228
- data/spec/rr/double/double_injection_reset_spec.rb +0 -86
- data/spec/rr/double/double_injection_spec.rb +0 -72
- data/spec/rr/double/double_injection_verify_spec.rb +0 -24
- data/spec/rr/double_definition_creator_proxy_spec.rb +0 -85
- data/spec/rr/double_definition_creator_spec.rb +0 -496
- data/spec/rr/double_definition_spec.rb +0 -815
- data/spec/rr/expectations/anything_spec.rb +0 -14
- data/spec/rr/expectations/boolean_spec.rb +0 -14
- data/spec/rr/expectations/duck_type_argument_equality_expectation_spec.rb +0 -71
- data/spec/rr/expectations/duck_type_spec.rb +0 -14
- data/spec/rr/expectations/is_a_argument_equality_expectation_spec.rb +0 -51
- data/spec/rr/expectations/is_a_spec.rb +0 -14
- data/spec/rr/expectations/numeric_argument_equality_expectation_spec.rb +0 -47
- data/spec/rr/expectations/numeric_spec.rb +0 -14
- data/spec/rr/expectations/range_argument_equality_expectation_spec.rb +0 -59
- data/spec/rr/expectations/range_spec.rb +0 -10
- data/spec/rr/expectations/regexp_argument_equality_expectation_spec.rb +0 -72
- data/spec/rr/expectations/regexp_spec.rb +0 -10
data/CHANGES
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
* 0.6.0
|
2
|
+
- Friendlier DoubleNotFound error message
|
3
|
+
- Implemented Double strategy creation methods (#mock, #stub, #proxy, #instance_of, and ! equivalents) on DoubleDefinition
|
4
|
+
- Implemented hash_including matcher (Patch by Matthew O'Conner)
|
5
|
+
- Implemented satisfy matcher (Patch by Matthew O'Conner)
|
6
|
+
- Implemented DoubleDefinitionCreator#mock!, #stub!, and #dont_allow!
|
7
|
+
- Modified api to method chain Doubles
|
8
|
+
- Fix conflict with Mocha overriding Object#verify
|
9
|
+
|
10
|
+
* 0.5.0
|
11
|
+
- Method chaining Doubles (Patch by Nick Kallen)
|
12
|
+
- Chained ordered expectations (Patch by Nick Kallen)
|
13
|
+
- Space#verify_doubles can take one or more objects with DoubleInjections to be verified
|
14
|
+
|
1
15
|
* 0.4.10
|
2
16
|
- DoubleDefinitionCreatorProxy does not undef #object_id
|
3
17
|
- Fixed rdoc pointer to README
|
data/README.rdoc
CHANGED
@@ -3,6 +3,15 @@
|
|
3
3
|
RR (Double Ruby) is a test double framework that features a rich
|
4
4
|
selection of double techniques and a terse syntax.
|
5
5
|
|
6
|
+
== More Information
|
7
|
+
=== Mailing Lists
|
8
|
+
* double-ruby-users@rubyforge.org
|
9
|
+
* double-ruby-devel@rubyforge.org
|
10
|
+
|
11
|
+
=== Websites
|
12
|
+
* http://rubyforge.org/projects/double-ruby
|
13
|
+
* http://github.com/btakita/rr
|
14
|
+
|
6
15
|
== What is a Test Double?
|
7
16
|
A Test Double is a generalization of something that replaces a real
|
8
17
|
object to make it easier to test another object. Its like a stunt
|
@@ -33,7 +42,7 @@ support spies.
|
|
33
42
|
== Syntax between RR and other double/mock frameworks
|
34
43
|
=== Terse Syntax
|
35
44
|
One of the goals of RR is to make doubles more scannable.
|
36
|
-
This is accomplished by
|
45
|
+
This is accomplished by making the double declaration look as much as the actual method invocation as possible.
|
37
46
|
Here is RR compared to other mock frameworks:
|
38
47
|
|
39
48
|
flexmock(User).should_receive(:find).with('42').and_return(jane) # Flexmock
|
@@ -42,10 +51,8 @@ Here is RR compared to other mock frameworks:
|
|
42
51
|
User.should_receive(:find).with('42') {jane} # Rspec using return value blocks
|
43
52
|
mock(User).find('42') {jane} # RR
|
44
53
|
|
45
|
-
===
|
46
|
-
RR
|
47
|
-
like other frameworks. Instead, RR utilizes a technique known as
|
48
|
-
"double injection".
|
54
|
+
=== Double Injections (a.k.a Partial Mocking)
|
55
|
+
RR utilizes a technique known as "double injection".
|
49
56
|
|
50
57
|
my_object = MyClass.new
|
51
58
|
mock(my_object).hello
|
@@ -54,10 +61,14 @@ Compare this with doing a mock in mocha:
|
|
54
61
|
my_mocked_object = mock()
|
55
62
|
my_mocked_object.expects(:hello)
|
56
63
|
|
64
|
+
== Pure Mock objects
|
57
65
|
If you wish to use objects for the sole purpose of being a mock, you can
|
58
66
|
do so by creating an empty object.
|
59
67
|
mock(my_mock_object = Object.new).hello
|
60
68
|
|
69
|
+
or by using mock!
|
70
|
+
my_mock_object = mock!.hello.subject # Mocks the #hello method and retrieves that object via the #subject method
|
71
|
+
|
61
72
|
=== No should_receive or expects method
|
62
73
|
RR uses method_missing to set your method expectation. This means you do not
|
63
74
|
need to use a method such as should_receive or expects.
|
@@ -70,7 +81,7 @@ Rspec mocks:
|
|
70
81
|
my_object.should_receive(:hello) # should_receive sets the hello method expectation
|
71
82
|
|
72
83
|
=== with method call is not necessary
|
73
|
-
Since RR uses method_missing, it also
|
84
|
+
Since RR uses method_missing, it also makes using the #with method unnecessary in most circumstances
|
74
85
|
to set the argument expectations.
|
75
86
|
|
76
87
|
mock(my_object).hello('bob', 'jane')
|
@@ -95,16 +106,19 @@ Rspec mocks:
|
|
95
106
|
|
96
107
|
== Using RR
|
97
108
|
To create a double on an object, you can use the following methods:
|
98
|
-
* mock
|
99
|
-
* stub
|
100
|
-
*
|
101
|
-
*
|
109
|
+
* mock or mock!
|
110
|
+
* stub or stub!
|
111
|
+
* dont_allow or dont_allow!
|
112
|
+
* proxy or proxy!
|
113
|
+
* instance_of or instance_of!
|
102
114
|
|
103
|
-
These methods are composable. mock and
|
115
|
+
These methods are composable. mock, stub, and dont_allow can be used by themselves and
|
104
116
|
are mutually exclusive.
|
105
|
-
proxy and instance_of must be chained with mock or stub. You can chain
|
117
|
+
proxy and instance_of must be chained with mock or stub. You can also chain
|
106
118
|
proxy and instance_of together.
|
107
119
|
|
120
|
+
The ! (bang) version of these methods causes the subject object of the Double to be instantiated.
|
121
|
+
|
108
122
|
=== mock
|
109
123
|
mock replaces the method on the object with an expectation and implementation.
|
110
124
|
The expectations are a mock will be called with certain arguments a certain
|
@@ -136,6 +150,12 @@ an exception is raised.
|
|
136
150
|
raise "Unexpected id #{id.inspect} passed to me"
|
137
151
|
end
|
138
152
|
|
153
|
+
=== dont_allow - aliased with do_not_allow, dont_call, and do_not_call
|
154
|
+
dont_allow sets an expectation on the Double that it will never be called.
|
155
|
+
If the Double is called, then a TimesCalledError is raised.
|
156
|
+
dont_allow(User).find('42')
|
157
|
+
User.find('42') # raises a TimesCalledError
|
158
|
+
|
139
159
|
=== mock.proxy
|
140
160
|
mock.proxy replaces the method on the object with an expectation, implementation, and
|
141
161
|
also invokes the actual method. mock.proxy also intercepts the return value and
|
@@ -190,6 +210,22 @@ Put double scenarios on instances of a Class.
|
|
190
210
|
m.system("rake baz") {true}
|
191
211
|
end
|
192
212
|
|
213
|
+
=== Double Graphs
|
214
|
+
RR has a method-chaining api support for Double graphs. For example,
|
215
|
+
lets say you want an object to receive a method call to #foo, and have
|
216
|
+
the return value receive a method call to #bar.
|
217
|
+
|
218
|
+
In RR, you would do:
|
219
|
+
stub(object).foo.stub!.bar {:baz}
|
220
|
+
object.foo.bar # :baz
|
221
|
+
# or
|
222
|
+
stub(object).foo {stub!.bar {:baz}}
|
223
|
+
object.foo.bar # :baz
|
224
|
+
# or
|
225
|
+
bar = stub!.bar {:baz}
|
226
|
+
stub(object).foo {bar}
|
227
|
+
object.foo.bar # :baz
|
228
|
+
|
193
229
|
=== Argument Wildcard matchers
|
194
230
|
==== anything
|
195
231
|
mock(object).foobar(1, anything)
|
@@ -214,6 +250,22 @@ Put double scenarios on instances of a Class.
|
|
214
250
|
def arg.talk; 'quack'; end
|
215
251
|
object.foobar(arg)
|
216
252
|
|
253
|
+
==== Ranges
|
254
|
+
mock(object).foobar(1..10)
|
255
|
+
object.foobar(5)
|
256
|
+
|
257
|
+
==== Regexps
|
258
|
+
mock(object).foobar(/on/)
|
259
|
+
object.foobar("ruby on rails")
|
260
|
+
|
261
|
+
==== hash_including
|
262
|
+
mock(object).foobar(hash_including(:red => "#FF0000", :blue => "#0000FF"))
|
263
|
+
object.foobar({:red => "#FF0000", :blue => "#0000FF", :green => "#00FF00"})
|
264
|
+
|
265
|
+
==== satisfy
|
266
|
+
mock(object).foobar(satisfy {|arg| arg.length == 2})
|
267
|
+
object.foobar("xy")
|
268
|
+
|
217
269
|
=== Invocation Amount Wildcard Matchers
|
218
270
|
==== any_times
|
219
271
|
mock(object).method_name(anything).times(any_times) {return_value}
|
@@ -222,10 +274,12 @@ Put double scenarios on instances of a Class.
|
|
222
274
|
With any development effort, there are countless people who have contributed
|
223
275
|
to making it possible. We all are standing on the shoulders of giants.
|
224
276
|
* Pivotal Labs for sponsoring RR development
|
277
|
+
* Nick Kallen for documentation suggestions, bug reports, and patches
|
278
|
+
* Matthew O'Conner for patches
|
279
|
+
* Nathan Sobo for various ideas and inspiration for cleaner and more expressive code
|
225
280
|
* Parker Thompson for pairing with me
|
226
281
|
* Felix Morio for pairing with me
|
227
282
|
* Jeff Whitmire for documentation suggestions
|
228
|
-
* Nick Kallen for documentation suggestion & bug reports
|
229
283
|
* David Chelimsky for encouragement to make the RR framework, for developing
|
230
284
|
the Rspec mock framework, and syntax ideas
|
231
285
|
* Gerard Meszaros for his excellent book "xUnit Test Patterns"
|
data/Rakefile
CHANGED
data/lib/rr.rb
CHANGED
@@ -10,13 +10,24 @@ require "#{dir}/rr/space"
|
|
10
10
|
require "#{dir}/rr/double_injection"
|
11
11
|
require "#{dir}/rr/hash_with_object_id_key"
|
12
12
|
|
13
|
-
require "#{dir}/rr/double_definition_creator_proxy"
|
14
|
-
|
15
|
-
require "#{dir}/rr/
|
13
|
+
require "#{dir}/rr/double_definitions/double_definition_creator_proxy"
|
14
|
+
require "#{dir}/rr/double_definitions/double_definition_creator"
|
15
|
+
require "#{dir}/rr/double_definitions/child_double_definition_creator"
|
16
|
+
require "#{dir}/rr/adapters/rr_methods"
|
16
17
|
|
17
18
|
require "#{dir}/rr/double"
|
18
|
-
require "#{dir}/rr/double_definition"
|
19
|
-
require "#{dir}/rr/
|
19
|
+
require "#{dir}/rr/double_definitions/double_definition"
|
20
|
+
require "#{dir}/rr/double_definitions/strategies/strategy"
|
21
|
+
require "#{dir}/rr/double_definitions/strategies/verification/verification_strategy"
|
22
|
+
require "#{dir}/rr/double_definitions/strategies/verification/mock"
|
23
|
+
require "#{dir}/rr/double_definitions/strategies/verification/stub"
|
24
|
+
require "#{dir}/rr/double_definitions/strategies/verification/dont_allow"
|
25
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/implementation_strategy"
|
26
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/reimplementation"
|
27
|
+
require "#{dir}/rr/double_definitions/strategies/implementation/proxy"
|
28
|
+
require "#{dir}/rr/double_definitions/strategies/scope/scope_strategy"
|
29
|
+
require "#{dir}/rr/double_definitions/strategies/scope/instance"
|
30
|
+
require "#{dir}/rr/double_definitions/strategies/scope/instance_of_class"
|
20
31
|
require "#{dir}/rr/double_matches"
|
21
32
|
|
22
33
|
require "#{dir}/rr/expectations/argument_equality_expectation"
|
@@ -30,6 +41,8 @@ require "#{dir}/rr/wildcard_matchers/boolean"
|
|
30
41
|
require "#{dir}/rr/wildcard_matchers/duck_type"
|
31
42
|
require "#{dir}/rr/wildcard_matchers/regexp"
|
32
43
|
require "#{dir}/rr/wildcard_matchers/range"
|
44
|
+
require "#{dir}/rr/wildcard_matchers/satisfy"
|
45
|
+
require "#{dir}/rr/wildcard_matchers/hash_including"
|
33
46
|
|
34
47
|
require "#{dir}/rr/times_called_matchers/terminal"
|
35
48
|
require "#{dir}/rr/times_called_matchers/non_terminal"
|
@@ -41,15 +54,22 @@ require "#{dir}/rr/times_called_matchers/proc_matcher"
|
|
41
54
|
require "#{dir}/rr/times_called_matchers/at_least_matcher"
|
42
55
|
require "#{dir}/rr/times_called_matchers/at_most_matcher"
|
43
56
|
|
44
|
-
require "#{dir}/rr/adapters/rr_methods"
|
45
|
-
|
46
57
|
require "#{dir}/rr/adapters/rspec"
|
47
58
|
require "#{dir}/rr/adapters/test_unit"
|
48
59
|
|
49
60
|
module RR
|
50
61
|
class << self
|
62
|
+
(RR::Space.instance_methods - Object.instance_methods).each do |method_name|
|
63
|
+
returns_method = <<-METHOD
|
64
|
+
def #{method_name}(*args, &block)
|
65
|
+
RR::Space.instance.__send__(:#{method_name}, *args, &block)
|
66
|
+
end
|
67
|
+
METHOD
|
68
|
+
class_eval(returns_method, __FILE__, __LINE__ - 4)
|
69
|
+
end
|
70
|
+
|
51
71
|
def method_missing(method_name, *args, &block)
|
52
72
|
RR::Space.instance.__send__(method_name, *args, &block)
|
53
73
|
end
|
54
|
-
end
|
55
|
-
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,6 +1,24 @@
|
|
1
1
|
module RR
|
2
2
|
module Adapters
|
3
3
|
module RRMethods
|
4
|
+
class << self
|
5
|
+
def register_strategy_class(strategy_class, method_name)
|
6
|
+
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
7
|
+
def #{method_name}(subject=DoubleDefinitions::DoubleDefinitionCreator::NO_SUBJECT, method_name=nil, &definition_eval_block)
|
8
|
+
creator = DoubleDefinitions::DoubleDefinitionCreator.new
|
9
|
+
creator.#{method_name}(subject, method_name, &definition_eval_block)
|
10
|
+
end
|
11
|
+
CLASS
|
12
|
+
|
13
|
+
class_eval((<<-CLASS), __FILE__, __LINE__ + 1)
|
14
|
+
def #{method_name}!(method_name=nil, &definition_eval_block)
|
15
|
+
creator = DoubleDefinitions::DoubleDefinitionCreator.new
|
16
|
+
creator.#{method_name}!(method_name, &definition_eval_block)
|
17
|
+
end
|
18
|
+
CLASS
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
4
22
|
# Verifies all the DoubleInjection objects have met their
|
5
23
|
# TimesCalledExpectations.
|
6
24
|
def verify
|
@@ -12,163 +30,6 @@ module RR
|
|
12
30
|
RR::Space.instance.reset
|
13
31
|
end
|
14
32
|
|
15
|
-
# This method sets the Double to have a mock strategy. A mock strategy
|
16
|
-
# sets the default state of the Double to expect the method call
|
17
|
-
# with arguments exactly one time. The Double's expectations can be
|
18
|
-
# changed.
|
19
|
-
#
|
20
|
-
# This method can be chained with proxy.
|
21
|
-
# mock.proxy(subject).method_name_1
|
22
|
-
# or
|
23
|
-
# proxy.mock(subject).method_name_1
|
24
|
-
#
|
25
|
-
# When passed the subject, a DoubleDefinitionCreatorProxy is returned. Passing
|
26
|
-
# a method with arguments to the proxy will set up expectations that
|
27
|
-
# the a call to the subject's method with the arguments will happen,
|
28
|
-
# and return the prescribed value.
|
29
|
-
# mock(subject).method_name_1 {return_value_1}
|
30
|
-
# mock(subject).method_name_2(arg1, arg2) {return_value_2}
|
31
|
-
#
|
32
|
-
# When passed the subject and the method_name, this method returns
|
33
|
-
# a mock Double with the method already set.
|
34
|
-
#
|
35
|
-
# mock(subject, :method_name_1) {return_value_1}
|
36
|
-
# mock(subject, :method_name_2).with(arg1, arg2) {return_value_2}
|
37
|
-
#
|
38
|
-
# mock also takes a block for definitions.
|
39
|
-
# mock(subject) do
|
40
|
-
# method_name_1 {return_value_1}
|
41
|
-
# method_name_2(arg_1, arg_2) {return_value_2}
|
42
|
-
# end
|
43
|
-
def mock(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
44
|
-
creator = DoubleDefinitionCreator.new
|
45
|
-
creator.mock(subject, method_name, &definition)
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
# This method sets the Double to have a stub strategy. A stub strategy
|
50
|
-
# sets the default state of the Double to expect the method call
|
51
|
-
# with any arguments any number of times. The Double's
|
52
|
-
# expectations can be changed.
|
53
|
-
#
|
54
|
-
# This method can be chained with proxy.
|
55
|
-
# stub.proxy(subject).method_name_1
|
56
|
-
# or
|
57
|
-
# proxy.stub(subject).method_name_1
|
58
|
-
#
|
59
|
-
# When passed the subject, a DoubleDefinitionCreatorProxy is returned. Passing
|
60
|
-
# a method with arguments to the proxy will set up expectations that
|
61
|
-
# the a call to the subject's method with the arguments will happen,
|
62
|
-
# and return the prescribed value.
|
63
|
-
# stub(subject).method_name_1 {return_value_1}
|
64
|
-
# stub(subject).method_name_2(arg_1, arg_2) {return_value_2}
|
65
|
-
#
|
66
|
-
# When passed the subject and the method_name, this method returns
|
67
|
-
# a stub Double with the method already set.
|
68
|
-
#
|
69
|
-
# mock(subject, :method_name_1) {return_value_1}
|
70
|
-
# mock(subject, :method_name_2).with(arg1, arg2) {return_value_2}
|
71
|
-
#
|
72
|
-
# stub also takes a block for definitions.
|
73
|
-
# stub(subject) do
|
74
|
-
# method_name_1 {return_value_1}
|
75
|
-
# method_name_2(arg_1, arg_2) {return_value_2}
|
76
|
-
# end
|
77
|
-
def stub(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
78
|
-
creator = DoubleDefinitionCreator.new
|
79
|
-
creator.stub(subject, method_name, &definition)
|
80
|
-
end
|
81
|
-
|
82
|
-
# This method add proxy capabilities to the Double. proxy can be called
|
83
|
-
# with mock or stub.
|
84
|
-
#
|
85
|
-
# mock.proxy(controller.template).render(:partial => "my/socks")
|
86
|
-
#
|
87
|
-
# stub.proxy(controller.template).render(:partial => "my/socks") do |html|
|
88
|
-
# html.should include("My socks are wet")
|
89
|
-
# html
|
90
|
-
# end
|
91
|
-
#
|
92
|
-
# mock.proxy(controller.template).render(:partial => "my/socks") do |html|
|
93
|
-
# html.should include("My socks are wet")
|
94
|
-
# "My new return value"
|
95
|
-
# end
|
96
|
-
#
|
97
|
-
# mock.proxy also takes a block for definitions.
|
98
|
-
# mock.proxy(subject) do
|
99
|
-
# render(:partial => "my/socks")
|
100
|
-
#
|
101
|
-
# render(:partial => "my/socks") do |html|
|
102
|
-
# html.should include("My socks are wet")
|
103
|
-
# html
|
104
|
-
# end
|
105
|
-
#
|
106
|
-
# render(:partial => "my/socks") do |html|
|
107
|
-
# html.should include("My socks are wet")
|
108
|
-
# html
|
109
|
-
# end
|
110
|
-
#
|
111
|
-
# render(:partial => "my/socks") do |html|
|
112
|
-
# html.should include("My socks are wet")
|
113
|
-
# "My new return value"
|
114
|
-
# end
|
115
|
-
# end
|
116
|
-
#
|
117
|
-
# Passing a block to the Double (after the method name and arguments)
|
118
|
-
# allows you to intercept the return value.
|
119
|
-
# The return value can be modified, validated, and/or overridden by
|
120
|
-
# passing in a block. The return value of the block will replace
|
121
|
-
# the actual return value.
|
122
|
-
#
|
123
|
-
# mock.proxy(controller.template).render(:partial => "my/socks") do |html|
|
124
|
-
# html.should include("My socks are wet")
|
125
|
-
# "My new return value"
|
126
|
-
# end
|
127
|
-
def proxy(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
128
|
-
creator = DoubleDefinitionCreator.new
|
129
|
-
creator.proxy(subject, method_name, &definition)
|
130
|
-
end
|
131
|
-
|
132
|
-
# This method sets the Double to have a dont_allow strategy.
|
133
|
-
# A dont_allow strategy sets the default state of the Double
|
134
|
-
# to expect never to be called. The Double's expectations can be
|
135
|
-
# changed.
|
136
|
-
#
|
137
|
-
# The following example sets the expectation that subject.method_name
|
138
|
-
# will never be called with arg1 and arg2.
|
139
|
-
#
|
140
|
-
# do_not_allow(subject).method_name(arg1, arg2)
|
141
|
-
#
|
142
|
-
# dont_allow also supports a block sytnax.
|
143
|
-
# dont_allow(subject) do |m|
|
144
|
-
# m.method1 # Do not allow method1 with any arguments
|
145
|
-
# m.method2(arg1, arg2) # Do not allow method2 with arguments arg1 and arg2
|
146
|
-
# m.method3.with_no_args # Do not allow method3 with no arguments
|
147
|
-
# end
|
148
|
-
def dont_allow(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
149
|
-
creator = DoubleDefinitionCreator.new
|
150
|
-
creator.dont_allow(subject, method_name, &definition)
|
151
|
-
end
|
152
|
-
alias_method :do_not_allow, :dont_allow
|
153
|
-
alias_method :dont_call, :dont_allow
|
154
|
-
alias_method :do_not_call, :dont_allow
|
155
|
-
|
156
|
-
# Calling instance_of will cause all instances of the passed in Class
|
157
|
-
# to have the Double defined.
|
158
|
-
#
|
159
|
-
# The following example mocks all User's valid? method and return false.
|
160
|
-
# mock.instance_of(User).valid? {false}
|
161
|
-
#
|
162
|
-
# The following example mocks and proxies User#projects and returns the
|
163
|
-
# first 3 projects.
|
164
|
-
# mock.instance_of(User).projects do |projects|
|
165
|
-
# projects[0..2]
|
166
|
-
# end
|
167
|
-
def instance_of(subject=DoubleDefinitionCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
168
|
-
creator = DoubleDefinitionCreator.new
|
169
|
-
creator.instance_of(subject, method_name, &definition)
|
170
|
-
end
|
171
|
-
|
172
33
|
# Returns a AnyTimesMatcher. This is meant to be passed in as an argument
|
173
34
|
# to Double#times.
|
174
35
|
#
|
@@ -210,7 +71,7 @@ module RR
|
|
210
71
|
end
|
211
72
|
|
212
73
|
# Sets up a DuckType wildcard ArgumentEqualityExpectation
|
213
|
-
# that succeeds when passed
|
74
|
+
# that succeeds when the passed argument implements the methods.
|
214
75
|
# arg = Object.new
|
215
76
|
# def arg.foo; end
|
216
77
|
# def arg.bar; end
|
@@ -219,6 +80,25 @@ module RR
|
|
219
80
|
def duck_type(*args)
|
220
81
|
RR::WildcardMatchers::DuckType.new(*args)
|
221
82
|
end
|
83
|
+
|
84
|
+
# Sets up a HashIncluding wildcard ArgumentEqualityExpectation
|
85
|
+
# that succeeds when the passed argument contains at least those keys
|
86
|
+
# and values of the expectation.
|
87
|
+
# mock(object).method_name(hash_including(:foo => 1)) {return_value}
|
88
|
+
# object.method_name({:foo => 1, :bar => 2) # passes
|
89
|
+
def hash_including(expected_hash)
|
90
|
+
RR::WildcardMatchers::HashIncluding.new(expected_hash)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Sets up a Satisfy wildcard ArgumentEqualityExpectation
|
94
|
+
# that succeeds when the passed argument causes the expectation's
|
95
|
+
# proc to return true.
|
96
|
+
# mock(object).method_name(satisfy {|arg| arg == :foo}) {return_value}
|
97
|
+
# object.method_name(:foo) # passes
|
98
|
+
def satisfy(expectation_proc=nil, &block)
|
99
|
+
expectation_proc ||= block
|
100
|
+
RR::WildcardMatchers::Satisfy.new(expectation_proc)
|
101
|
+
end
|
222
102
|
|
223
103
|
instance_methods.each do |name|
|
224
104
|
alias_method "rr_#{name}", name
|