rspec-mocks 2.6.0 → 2.7.0.rc1
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.
- data/features/Scope.md +17 -0
- data/features/argument_matchers/README.md +27 -0
- data/features/argument_matchers/explicit.feature +60 -0
- data/features/argument_matchers/general_matchers.feature +85 -0
- data/features/argument_matchers/type_matchers.feature +25 -0
- data/features/message_expectations/any_instance.feature +2 -0
- data/features/message_expectations/receive_counts.feature +209 -0
- data/features/method_stubs/README.md +6 -10
- data/features/method_stubs/any_instance.feature +111 -1
- data/features/method_stubs/simple_return_value.feature +34 -25
- data/features/method_stubs/stub_implementation.feature +1 -1
- data/features/method_stubs/to_ary.feature +12 -10
- data/features/support/env.rb +1 -1
- data/lib/rspec/mocks.rb +1 -1
- data/lib/rspec/mocks/any_instance.rb +8 -235
- data/lib/rspec/mocks/any_instance/chain.rb +49 -0
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +33 -0
- data/lib/rspec/mocks/any_instance/message_chains.rb +48 -0
- data/lib/rspec/mocks/any_instance/recorder.rb +162 -0
- data/lib/rspec/mocks/any_instance/stub_chain.rb +35 -0
- data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +34 -0
- data/lib/rspec/mocks/argument_expectation.rb +1 -1
- data/lib/rspec/mocks/extensions/marshal.rb +1 -1
- data/lib/rspec/mocks/extensions/psych.rb +1 -1
- data/lib/rspec/mocks/methods.rb +1 -1
- data/lib/rspec/mocks/mock.rb +2 -2
- data/lib/rspec/mocks/proxy.rb +1 -1
- data/lib/rspec/mocks/version.rb +1 -1
- data/spec/rspec/mocks/any_instance/message_chains_spec.rb +40 -0
- data/spec/rspec/mocks/any_instance_spec.rb +147 -2
- data/spec/rspec/mocks/any_number_of_times_spec.rb +2 -2
- data/spec/rspec/mocks/argument_expectation_spec.rb +15 -3
- data/spec/rspec/mocks/at_least_spec.rb +1 -1
- data/spec/rspec/mocks/at_most_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_10263_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_7611_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_8165_spec.rb +2 -2
- data/spec/rspec/mocks/bug_report_957_spec.rb +2 -2
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +1 -1
- data/spec/rspec/mocks/hash_including_matcher_spec.rb +11 -11
- data/spec/rspec/mocks/hash_not_including_matcher_spec.rb +6 -6
- data/spec/rspec/mocks/mock_spec.rb +49 -43
- data/spec/rspec/mocks/multiple_return_value_spec.rb +26 -26
- data/spec/rspec/mocks/partial_mock_spec.rb +3 -2
- data/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb +1 -0
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +3 -3
- data/spec/rspec/mocks/precise_counts_spec.rb +1 -1
- data/spec/rspec/mocks/serialization_spec.rb +7 -2
- data/spec/rspec/mocks/stub_implementation_spec.rb +6 -6
- data/spec/rspec/mocks/stub_spec.rb +6 -6
- data/spec/rspec/mocks/to_ary_spec.rb +9 -0
- metadata +54 -47
- data/.autotest +0 -7
- data/.document +0 -5
- data/.gitignore +0 -10
- data/.travis.yml +0 -7
- data/Gemfile +0 -40
- data/Guardfile +0 -8
- data/License.txt +0 -22
- data/Rakefile +0 -75
- data/autotest/discover.rb +0 -1
- data/cucumber.yml +0 -2
- data/features/.nav +0 -17
- data/features/Changelog.md +0 -80
- data/rspec-mocks.gemspec +0 -25
- data/specs.watchr +0 -57
data/features/Scope.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Doubles, stubs, and message expectations are all cleaned out after each
|
2
|
+
example. This ensures that each example can be run in isolation, and in any
|
3
|
+
order.
|
4
|
+
|
5
|
+
### `before(:each)`
|
6
|
+
|
7
|
+
It is perfectly fine to set up doubles, stubs, and message expectations in
|
8
|
+
a `before(:each)` hook, as that hook is executed in the scope of the example:
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
@account = double('account')
|
12
|
+
end
|
13
|
+
|
14
|
+
### Do not create doubles, stubs, or message expectations in `before(:all)`
|
15
|
+
|
16
|
+
If you do, they'll get cleaned out after the first example, and you will be
|
17
|
+
very confused as to what's going on in the second example.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
### Introduction
|
2
|
+
|
3
|
+
Argument matchers can be used:
|
4
|
+
|
5
|
+
* In stubs to constrain the scope of the stubbed method
|
6
|
+
|
7
|
+
obj.stub(:foo).with(:bar) do |arg|
|
8
|
+
#do something for :bar
|
9
|
+
end
|
10
|
+
obj.stub(:foo).with(:baz) do |arg|
|
11
|
+
#do something for :baz
|
12
|
+
end
|
13
|
+
|
14
|
+
* In expectations to validate the arguments that should be received in a method call
|
15
|
+
|
16
|
+
#create a double
|
17
|
+
obj = double()
|
18
|
+
|
19
|
+
#expect a message with given args
|
20
|
+
obj.should_receive(:message).with('an argument')
|
21
|
+
|
22
|
+
If more control is needed, one can use a block
|
23
|
+
|
24
|
+
obj.should_receive(:message) do |arg1, arg2|
|
25
|
+
# set expectations about the args in this block
|
26
|
+
# and optionally set a return value
|
27
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
Feature: explicit arguments
|
2
|
+
|
3
|
+
Allows you to explicitly specify the argument values
|
4
|
+
|
5
|
+
Scenario: explicit arguments
|
6
|
+
Given a file named "stub_explicit_args_spec.rb" with:
|
7
|
+
"""
|
8
|
+
describe "stubbed explicit arguments" do
|
9
|
+
it "works on stubs" do
|
10
|
+
object = Object.new
|
11
|
+
object.stub(:foo).with(:this) do |arg|
|
12
|
+
"got this"
|
13
|
+
end
|
14
|
+
object.stub(:foo).with(:that) do |arg|
|
15
|
+
"got that"
|
16
|
+
end
|
17
|
+
|
18
|
+
object.foo(:this).should eq("got this")
|
19
|
+
object.foo(:that).should eq("got that")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "works on doubles and expectations" do
|
23
|
+
object = double('foo')
|
24
|
+
object.should_receive(:bar).with(:foo)
|
25
|
+
|
26
|
+
object.bar(:foo)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
"""
|
30
|
+
When I run `rspec stub_explicit_args_spec.rb`
|
31
|
+
Then the output should contain "2 examples, 0 failures"
|
32
|
+
|
33
|
+
Scenario: explicit arguments with multiple arities
|
34
|
+
Given a file named "stub_multiple_explicit_args_spec.rb" with:
|
35
|
+
"""
|
36
|
+
describe "stubbed multiple explicit arguments" do
|
37
|
+
it "works on stubs" do
|
38
|
+
object = Object.new
|
39
|
+
object.stub(:foo).with(:this) do |arg|
|
40
|
+
"got this"
|
41
|
+
end
|
42
|
+
object.stub(:foo).with(:this, :that) do |arg1, arg2|
|
43
|
+
"got this and that"
|
44
|
+
end
|
45
|
+
|
46
|
+
object.foo(:this).should eq("got this")
|
47
|
+
object.foo(:this, :that).should eq("got this and that")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "works on mocks" do
|
51
|
+
object = double('foo')
|
52
|
+
object.should_receive(:foo).with(:this, :that)
|
53
|
+
|
54
|
+
object.foo(:this, :that)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
"""
|
58
|
+
When I run `rspec stub_multiple_explicit_args_spec.rb`
|
59
|
+
Then the output should contain "2 examples, 0 failures"
|
60
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
Feature: General matchers
|
2
|
+
|
3
|
+
The `anything`, `any_args`, and `no_args` matchers can be used to require the method
|
4
|
+
to have arguments (or not) without constraining the details of the argument, such as its
|
5
|
+
type, pattern or value. The `anything` matcher only reflects a single argument, while
|
6
|
+
the `any_args` matcher matches any arity.
|
7
|
+
|
8
|
+
Scenario: anything argument matcher
|
9
|
+
Given a file named "stub_anything_args_spec.rb" with:
|
10
|
+
"""
|
11
|
+
describe "stubbed anything() args spec" do
|
12
|
+
it "works" do
|
13
|
+
object = Object.new
|
14
|
+
object.stub(:foo).with(anything) do
|
15
|
+
"anything"
|
16
|
+
end
|
17
|
+
|
18
|
+
object.foo(1).should eq("anything")
|
19
|
+
object.foo(:that).should eq("anything")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
"""
|
23
|
+
When I run `rspec stub_anything_args_spec.rb`
|
24
|
+
Then the output should contain "1 example, 0 failures"
|
25
|
+
|
26
|
+
Scenario: any_args argument matcher
|
27
|
+
Given a file named "stub_any_args_spec.rb" with:
|
28
|
+
"""
|
29
|
+
describe "stubbed any_args() args spec" do
|
30
|
+
it "works" do
|
31
|
+
object = Object.new
|
32
|
+
object.stub(:foo).with(any_args) do
|
33
|
+
"anything"
|
34
|
+
end
|
35
|
+
|
36
|
+
object.foo(1).should eq("anything")
|
37
|
+
object.foo(:that).should eq("anything")
|
38
|
+
object.foo.should eq("anything")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
"""
|
42
|
+
When I run `rspec stub_any_args_spec.rb`
|
43
|
+
Then the output should contain "1 example, 0 failures"
|
44
|
+
|
45
|
+
Scenario: no_args argument matcher
|
46
|
+
Given a file named "stub_no_args_spec.rb" with:
|
47
|
+
"""
|
48
|
+
describe "stubbed no_args() args spec" do
|
49
|
+
it "works for no args" do
|
50
|
+
object = Object.new
|
51
|
+
object.stub(:foo).with(no_args) do
|
52
|
+
"nothing"
|
53
|
+
end
|
54
|
+
object.stub(:foo).with(anything) do
|
55
|
+
"something"
|
56
|
+
end
|
57
|
+
|
58
|
+
object.foo(:that).should eq("something")
|
59
|
+
object.foo.should eq("nothing")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
"""
|
63
|
+
When I run `rspec stub_no_args_spec.rb`
|
64
|
+
Then the output should contain "1 example, 0 failures"
|
65
|
+
|
66
|
+
Scenario: no_args argument matcher for expectations
|
67
|
+
Given a file named "stub_no_args_expectations_spec.rb" with:
|
68
|
+
"""
|
69
|
+
describe "stubbed no_args() args spec for expectations" do
|
70
|
+
it "works for no args" do
|
71
|
+
object = Object.new
|
72
|
+
object.should_receive(:foo).with(no_args)
|
73
|
+
|
74
|
+
object.foo
|
75
|
+
end
|
76
|
+
it "fails for args" do
|
77
|
+
object = Object.new
|
78
|
+
object.should_receive(:foo).with(no_args)
|
79
|
+
|
80
|
+
object.foo(:bar)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
"""
|
84
|
+
When I run `rspec stub_no_args_expectations_spec.rb`
|
85
|
+
Then the output should contain "2 examples, 1 failure"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: stub with argument constraints
|
2
|
+
|
3
|
+
You can further specify the behavior by constraining the type, format and/or number of arguments with the #with() method chained off of #stub()
|
4
|
+
|
5
|
+
Scenario: an_instance_of argument matcher
|
6
|
+
Given a file named "stub_an_instance_of_args_spec.rb" with:
|
7
|
+
"""
|
8
|
+
describe "stubbed an_instance_of() args spec" do
|
9
|
+
it "works" do
|
10
|
+
object = Object.new
|
11
|
+
object.stub(:foo).with(an_instance_of(Symbol)) do
|
12
|
+
"symbol"
|
13
|
+
end
|
14
|
+
object.stub(:foo).with(an_instance_of(String)) do
|
15
|
+
"string"
|
16
|
+
end
|
17
|
+
|
18
|
+
object.foo("bar").should eq("string")
|
19
|
+
object.foo(:that).should eq("symbol")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
"""
|
23
|
+
When I run `rspec stub_an_instance_of_args_spec.rb`
|
24
|
+
Then the output should contain "1 example, 0 failures"
|
25
|
+
|
@@ -2,6 +2,8 @@ Feature: expect a message on any instance of a class
|
|
2
2
|
|
3
3
|
Use `any_instance.should_receive` to set an expectation that one (and only
|
4
4
|
one) instance of a class receives a message before the example is completed.
|
5
|
+
|
6
|
+
The spec will fail if no instance receives a message.
|
5
7
|
|
6
8
|
Scenario: expect a message on any instance of a class
|
7
9
|
Given a file named "example_spec.rb" with:
|
@@ -0,0 +1,209 @@
|
|
1
|
+
Feature: receive counts
|
2
|
+
|
3
|
+
Scenario: expect a message once
|
4
|
+
Given a file named "spec/account_spec.rb" with:
|
5
|
+
"""
|
6
|
+
class Account
|
7
|
+
attr_accessor :logger
|
8
|
+
|
9
|
+
def open
|
10
|
+
logger.account_opened
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Account do
|
15
|
+
context "when opened" do
|
16
|
+
it "logger#account_opened was called once" do
|
17
|
+
logger = double("logger")
|
18
|
+
account = Account.new
|
19
|
+
account.logger = logger
|
20
|
+
|
21
|
+
logger.should_receive(:account_opened).once
|
22
|
+
|
23
|
+
account.open
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
"""
|
28
|
+
When I run `rspec spec/account_spec.rb`
|
29
|
+
Then the output should contain "1 example, 0 failures"
|
30
|
+
|
31
|
+
Scenario: expect a message twice
|
32
|
+
Given a file named "spec/account_spec.rb" with:
|
33
|
+
"""
|
34
|
+
class Account
|
35
|
+
attr_accessor :logger
|
36
|
+
|
37
|
+
def open
|
38
|
+
logger.account_opened
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe Account do
|
43
|
+
context "when opened" do
|
44
|
+
it "logger#account_opened was called once" do
|
45
|
+
logger = double("logger")
|
46
|
+
account = Account.new
|
47
|
+
account.logger = logger
|
48
|
+
|
49
|
+
logger.should_receive(:account_opened).twice
|
50
|
+
|
51
|
+
account.open
|
52
|
+
account.open
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
"""
|
57
|
+
When I run `rspec spec/account_spec.rb`
|
58
|
+
Then the output should contain "1 example, 0 failures"
|
59
|
+
|
60
|
+
Scenario: expect a message 3 times
|
61
|
+
Given a file named "spec/account_spec.rb" with:
|
62
|
+
"""
|
63
|
+
class Account
|
64
|
+
attr_accessor :logger
|
65
|
+
|
66
|
+
def open
|
67
|
+
logger.account_opened
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe Account do
|
72
|
+
context "when opened" do
|
73
|
+
it "logger#account_opened was called once" do
|
74
|
+
logger = double("logger")
|
75
|
+
account = Account.new
|
76
|
+
account.logger = logger
|
77
|
+
|
78
|
+
logger.should_receive(:account_opened).exactly(3).times
|
79
|
+
|
80
|
+
account.open
|
81
|
+
account.open
|
82
|
+
account.open
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
"""
|
87
|
+
When I run `rspec spec/account_spec.rb`
|
88
|
+
Then the output should contain "1 example, 0 failures"
|
89
|
+
|
90
|
+
Scenario: expect a message at least (:once)
|
91
|
+
Given a file named "spec/account_spec.rb" with:
|
92
|
+
"""
|
93
|
+
class Account
|
94
|
+
attr_accessor :logger
|
95
|
+
|
96
|
+
def open
|
97
|
+
logger.account_opened
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe Account do
|
102
|
+
context "when opened" do
|
103
|
+
it "logger#account_opened was called once" do
|
104
|
+
logger = double("logger")
|
105
|
+
account = Account.new
|
106
|
+
account.logger = logger
|
107
|
+
|
108
|
+
logger.should_receive(:account_opened).at_least(:once)
|
109
|
+
|
110
|
+
account.open
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
"""
|
115
|
+
When I run `rspec spec/account_spec.rb`
|
116
|
+
Then the output should contain "1 example, 0 failures"
|
117
|
+
|
118
|
+
|
119
|
+
Scenario: expect a message at least (n) times
|
120
|
+
Given a file named "spec/account_spec.rb" with:
|
121
|
+
"""
|
122
|
+
class Account
|
123
|
+
attr_accessor :logger
|
124
|
+
|
125
|
+
def open
|
126
|
+
logger.account_opened
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe Account do
|
131
|
+
context "when opened" do
|
132
|
+
it "logger#account_opened was called once" do
|
133
|
+
logger = double("logger")
|
134
|
+
account = Account.new
|
135
|
+
account.logger = logger
|
136
|
+
|
137
|
+
logger.should_receive(:account_opened).at_least(3).times
|
138
|
+
|
139
|
+
# Note that I am calling method under test 4 times
|
140
|
+
# and I specified it to be called at least 3 times
|
141
|
+
account.open
|
142
|
+
account.open
|
143
|
+
account.open
|
144
|
+
account.open
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
"""
|
149
|
+
When I run `rspec spec/account_spec.rb`
|
150
|
+
Then the output should contain "1 example, 0 failures"
|
151
|
+
|
152
|
+
Scenario: expect a message at most (:once)
|
153
|
+
Given a file named "spec/account_spec.rb" with:
|
154
|
+
"""
|
155
|
+
class Account
|
156
|
+
attr_accessor :logger
|
157
|
+
|
158
|
+
def open
|
159
|
+
logger.account_opened
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe Account do
|
164
|
+
context "when opened" do
|
165
|
+
it "logger#account_opened was called once" do
|
166
|
+
logger = double("logger")
|
167
|
+
account = Account.new
|
168
|
+
account.logger = logger
|
169
|
+
|
170
|
+
logger.should_receive(:account_opened).at_most(:once)
|
171
|
+
|
172
|
+
account.open
|
173
|
+
account.open
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
"""
|
178
|
+
When I run `rspec spec/account_spec.rb`
|
179
|
+
Then the output should contain "expected: 1 time"
|
180
|
+
And the output should contain "received: 2 times"
|
181
|
+
|
182
|
+
Scenario: expect a message at most (n) times
|
183
|
+
Given a file named "spec/account_spec.rb" with:
|
184
|
+
"""
|
185
|
+
class Account
|
186
|
+
attr_accessor :logger
|
187
|
+
|
188
|
+
def open
|
189
|
+
logger.account_opened
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe Account do
|
194
|
+
context "when opened" do
|
195
|
+
it "logger#account_opened was called once" do
|
196
|
+
logger = double("logger")
|
197
|
+
account = Account.new
|
198
|
+
account.logger = logger
|
199
|
+
|
200
|
+
logger.should_receive(:account_opened).at_most(2).times
|
201
|
+
|
202
|
+
account.open
|
203
|
+
account.open
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
"""
|
208
|
+
When I run `rspec spec/account_spec.rb`
|
209
|
+
Then the output should contain "1 example, 0 failures"
|
@@ -1,15 +1,12 @@
|
|
1
1
|
### Stub return values
|
2
2
|
|
3
|
-
obj.stub(:message)
|
4
|
-
obj.stub(:message
|
3
|
+
obj.stub(:message) { :value }
|
4
|
+
obj.stub(:message => :value)
|
5
|
+
obj.stub(:message).and_return(:value)
|
5
6
|
|
6
|
-
These
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
The block format is generally preferred as it is more terse and more consistent
|
11
|
-
with other forms described below, but lazy evaluation can be confusing because
|
12
|
-
things aren't evaluated in the order in which they are declared.
|
7
|
+
These forms are somewhat interchangeable. The difference is that the block
|
8
|
+
contents are evaluated lazily when the `obj` receives the `message` message,
|
9
|
+
whereas the others are evaluated as they are read.
|
13
10
|
|
14
11
|
### Fake implementation
|
15
12
|
|
@@ -44,4 +41,3 @@ You can also use the block format, for consistency with other stubs:
|
|
44
41
|
#### Regular expressions
|
45
42
|
|
46
43
|
obj.stub(:message).with(/abc/) { ... }
|
47
|
-
|