rspec-mocks 3.0.0.beta1 → 3.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +1 -1
- data/Changelog.md +95 -3
- data/README.md +27 -13
- data/features/README.md +15 -7
- data/features/argument_matchers/README.md +5 -5
- data/features/argument_matchers/explicit.feature +6 -6
- data/features/argument_matchers/general_matchers.feature +4 -4
- data/features/argument_matchers/type_matchers.feature +2 -2
- data/features/message_expectations/README.md +29 -27
- data/features/message_expectations/call_original.feature +0 -1
- data/features/message_expectations/message_chains_using_expect.feature +49 -0
- data/features/method_stubs/README.md +2 -1
- data/features/method_stubs/{any_instance.feature → allow_any_instance_of.feature} +12 -12
- data/features/method_stubs/{stub_chain.feature → receive_message_chain.feature} +3 -3
- data/features/method_stubs/to_ary.feature +1 -1
- data/features/mutating_constants/stub_defined_constant.feature +0 -1
- data/features/outside_rspec/standalone.feature +1 -1
- data/features/spies/spy_pure_mock_method.feature +1 -1
- data/features/test_frameworks/test_unit.feature +21 -10
- data/features/verifying_doubles/README.md +17 -0
- data/features/verifying_doubles/class_doubles.feature +1 -16
- data/features/verifying_doubles/dynamic_classes.feature +0 -1
- data/features/verifying_doubles/{introduction.feature → instance_doubles.feature} +41 -23
- data/features/verifying_doubles/partial_doubles.feature +2 -2
- data/lib/rspec/mocks.rb +69 -82
- data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +35 -0
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +1 -2
- data/lib/rspec/mocks/any_instance/recorder.rb +52 -18
- data/lib/rspec/mocks/any_instance/stub_chain.rb +1 -1
- data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +4 -0
- data/lib/rspec/mocks/argument_list_matcher.rb +10 -44
- data/lib/rspec/mocks/argument_matchers.rb +132 -163
- data/lib/rspec/mocks/configuration.rb +28 -4
- data/lib/rspec/mocks/error_generator.rb +46 -13
- data/lib/rspec/mocks/example_methods.rb +13 -12
- data/lib/rspec/mocks/extensions/marshal.rb +1 -1
- data/lib/rspec/mocks/framework.rb +3 -4
- data/lib/rspec/mocks/instance_method_stasher.rb +2 -3
- data/lib/rspec/mocks/matchers/have_received.rb +8 -6
- data/lib/rspec/mocks/matchers/receive.rb +28 -20
- data/lib/rspec/mocks/matchers/receive_message_chain.rb +65 -0
- data/lib/rspec/mocks/matchers/receive_messages.rb +3 -2
- data/lib/rspec/mocks/message_chain.rb +91 -0
- data/lib/rspec/mocks/message_expectation.rb +86 -80
- data/lib/rspec/mocks/method_double.rb +2 -11
- data/lib/rspec/mocks/method_reference.rb +82 -23
- data/lib/rspec/mocks/method_signature_verifier.rb +207 -0
- data/lib/rspec/mocks/mutate_const.rb +34 -50
- data/lib/rspec/mocks/object_reference.rb +0 -1
- data/lib/rspec/mocks/proxy.rb +70 -13
- data/lib/rspec/mocks/ruby_features.rb +24 -0
- data/lib/rspec/mocks/space.rb +105 -31
- data/lib/rspec/mocks/standalone.rb +2 -2
- data/lib/rspec/mocks/syntax.rb +43 -8
- data/lib/rspec/mocks/targets.rb +16 -7
- data/lib/rspec/mocks/test_double.rb +41 -15
- data/lib/rspec/mocks/verifying_double.rb +51 -4
- data/lib/rspec/mocks/verifying_message_expecation.rb +12 -12
- data/lib/rspec/mocks/verifying_proxy.rb +32 -19
- data/lib/rspec/mocks/version.rb +1 -1
- data/spec/rspec/mocks/and_call_original_spec.rb +28 -7
- data/spec/rspec/mocks/and_return_spec.rb +23 -0
- data/spec/rspec/mocks/and_yield_spec.rb +1 -2
- data/spec/rspec/mocks/any_instance_spec.rb +33 -17
- data/spec/rspec/mocks/array_including_matcher_spec.rb +6 -6
- data/spec/rspec/mocks/before_all_spec.rb +132 -0
- data/spec/rspec/mocks/block_return_value_spec.rb +12 -1
- data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +9 -11
- data/spec/rspec/mocks/configuration_spec.rb +14 -1
- data/spec/rspec/mocks/double_spec.rb +867 -24
- data/spec/rspec/mocks/example_methods_spec.rb +13 -0
- data/spec/rspec/mocks/extensions/marshal_spec.rb +17 -17
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +29 -1
- data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +12 -12
- data/spec/rspec/mocks/hash_including_matcher_spec.rb +21 -17
- data/spec/rspec/mocks/instance_method_stasher_spec.rb +2 -3
- data/spec/rspec/mocks/matchers/have_received_spec.rb +7 -0
- data/spec/rspec/mocks/matchers/receive_message_chain_spec.rb +198 -0
- data/spec/rspec/mocks/matchers/receive_messages_spec.rb +2 -2
- data/spec/rspec/mocks/matchers/receive_spec.rb +19 -6
- data/spec/rspec/mocks/method_signature_verifier_spec.rb +272 -0
- data/spec/rspec/mocks/methods_spec.rb +0 -1
- data/spec/rspec/mocks/multiple_return_value_spec.rb +2 -2
- data/spec/rspec/mocks/mutate_const_spec.rb +24 -1
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +6 -22
- data/spec/rspec/mocks/null_object_mock_spec.rb +13 -7
- data/spec/rspec/mocks/options_hash_spec.rb +3 -3
- data/spec/rspec/mocks/{partial_mock_spec.rb → partial_double_spec.rb} +5 -2
- data/spec/rspec/mocks/{partial_mock_using_mocks_directly_spec.rb → partial_double_using_mocks_directly_spec.rb} +1 -1
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +18 -0
- data/spec/rspec/mocks/serialization_spec.rb +1 -0
- data/spec/rspec/mocks/space_spec.rb +218 -7
- data/spec/rspec/mocks/stub_chain_spec.rb +6 -0
- data/spec/rspec/mocks/stub_spec.rb +0 -6
- data/spec/rspec/mocks/syntax_spec.rb +19 -0
- data/spec/rspec/mocks/test_double_spec.rb +0 -1
- data/spec/rspec/mocks/verifying_double_spec.rb +281 -18
- data/spec/rspec/mocks/verifying_message_expecation_spec.rb +7 -6
- data/spec/rspec/mocks_spec.rb +168 -42
- data/spec/spec_helper.rb +34 -22
- metadata +94 -63
- metadata.gz.sig +0 -0
- checksums.yaml +0 -15
- checksums.yaml.gz.sig +0 -2
- data/features/outside_rspec/configuration.feature +0 -60
- data/lib/rspec/mocks/arity_calculator.rb +0 -66
- data/lib/rspec/mocks/errors.rb +0 -12
- data/lib/rspec/mocks/mock.rb +0 -7
- data/lib/rspec/mocks/proxy_for_nil.rb +0 -37
- data/lib/rspec/mocks/stub_chain.rb +0 -51
- data/spec/rspec/mocks/argument_expectation_spec.rb +0 -32
- data/spec/rspec/mocks/arity_calculator_spec.rb +0 -95
- data/spec/rspec/mocks/mock_space_spec.rb +0 -113
- data/spec/rspec/mocks/mock_spec.rb +0 -788
@@ -0,0 +1,49 @@
|
|
1
|
+
Feature: Message chains in the expect syntax
|
2
|
+
|
3
|
+
You can use `receive_message_chain` to stub nested calls
|
4
|
+
on both partial and pure mock objects.
|
5
|
+
|
6
|
+
Scenario: allow a chained message
|
7
|
+
Given a file named "spec/chained_messages.rb" with:
|
8
|
+
"""ruby
|
9
|
+
describe "a chained message expectation" do
|
10
|
+
it "passes if the expected number of calls happen" do
|
11
|
+
d = double
|
12
|
+
allow(d).to receive_message_chain(:to_a, :length)
|
13
|
+
|
14
|
+
d.to_a.length
|
15
|
+
end
|
16
|
+
end
|
17
|
+
"""
|
18
|
+
When I run `rspec spec/chained_messages.rb`
|
19
|
+
Then the output should contain "1 example, 0 failures"
|
20
|
+
|
21
|
+
Scenario: allow a chained message with a return value
|
22
|
+
Given a file named "spec/chained_messages.rb" with:
|
23
|
+
"""ruby
|
24
|
+
describe "a chained message expectation" do
|
25
|
+
it "passes if the expected number of calls happen" do
|
26
|
+
d = double
|
27
|
+
allow(d).to receive_message_chain(:to_a, :length).and_return(3)
|
28
|
+
|
29
|
+
expect(d.to_a.length).to eq(3)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
"""
|
33
|
+
When I run `rspec spec/chained_messages.rb`
|
34
|
+
Then the output should contain "1 example, 0 failures"
|
35
|
+
|
36
|
+
Scenario: expect a chained message with a return value
|
37
|
+
Given a file named "spec/chained_messages.rb" with:
|
38
|
+
"""ruby
|
39
|
+
describe "a chained message expectation" do
|
40
|
+
it "passes if the expected number of calls happen" do
|
41
|
+
d = double
|
42
|
+
expect(d).to receive_message_chain(:to_a, :length).and_return(3)
|
43
|
+
|
44
|
+
expect(d.to_a.length).to eq(3)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
"""
|
48
|
+
When I run `rspec spec/chained_messages.rb`
|
49
|
+
Then the output should contain "1 example, 0 failures"
|
@@ -20,7 +20,7 @@ block contents are evaluated lazily when the `obj` receives the
|
|
20
20
|
|
21
21
|
allow(obj).to receive(:message) do |arg1, arg2|
|
22
22
|
# set expectations about the args in this block
|
23
|
-
# and/or return
|
23
|
+
# and/or return value
|
24
24
|
end
|
25
25
|
|
26
26
|
obj.stub(:message) do |arg1, arg2|
|
@@ -49,6 +49,7 @@ You can also use the block format:
|
|
49
49
|
#### Explicit arguments
|
50
50
|
|
51
51
|
allow(obj).to receive(:message).with('an argument') { ... }
|
52
|
+
allow(obj).to receive(:message).with('more than', 'an argument') { ... }
|
52
53
|
|
53
54
|
obj.stub(:message).with('an argument') { ... }
|
54
55
|
obj.stub(:message).with('more_than', 'one_argument') { ... }
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Feature: stub on any instance of a class
|
2
2
|
|
3
|
-
Use `
|
3
|
+
Use `allow_any_instance_of` on a class to tell any instance of that class to
|
4
4
|
return a value (or values) in response to a given message. If no instance
|
5
5
|
receives the message, nothing happens.
|
6
6
|
|
@@ -10,12 +10,12 @@ Feature: stub on any instance of a class
|
|
10
10
|
to the object that receives a message in your test. For more information,
|
11
11
|
see the message_expectations/allow_any_instance_of feature.
|
12
12
|
|
13
|
-
Scenario:
|
13
|
+
Scenario: Stubbing any instance of an object with a single return value
|
14
14
|
Given a file named "example_spec.rb" with:
|
15
15
|
"""ruby
|
16
|
-
describe "
|
16
|
+
describe "stubbing any instance" do
|
17
17
|
it "returns the specified value on any instance of the class" do
|
18
|
-
Object.
|
18
|
+
allow_any_instance_of(Object).to receive(:foo).and_return(:return_value)
|
19
19
|
|
20
20
|
o = Object.new
|
21
21
|
expect(o.foo).to eq(:return_value)
|
@@ -31,7 +31,7 @@ Feature: stub on any instance of a class
|
|
31
31
|
describe "any_instance.stub" do
|
32
32
|
context "with a hash" do
|
33
33
|
it "returns the hash values on any instance of the class" do
|
34
|
-
Object.
|
34
|
+
allow_any_instance_of(Object).to receive_messages(:foo => 'foo', :bar => 'bar')
|
35
35
|
|
36
36
|
o = Object.new
|
37
37
|
expect(o.foo).to eq('foo')
|
@@ -43,14 +43,14 @@ Feature: stub on any instance of a class
|
|
43
43
|
When I run `rspec example_spec.rb`
|
44
44
|
Then the examples should all pass
|
45
45
|
|
46
|
-
Scenario:
|
46
|
+
Scenario: Stubbing any instance of an object with specific arguments matchers
|
47
47
|
Given a file named "example_spec.rb" with:
|
48
48
|
"""ruby
|
49
|
-
describe "
|
49
|
+
describe "stubbing any instance" do
|
50
50
|
context "with arguments" do
|
51
51
|
it "returns the stubbed value when arguments match" do
|
52
|
-
Object.
|
53
|
-
Object.
|
52
|
+
allow_any_instance_of(Object).to receive(:foo).with(:param_one, :param_two).and_return(:result_one)
|
53
|
+
allow_any_instance_of(Object).to receive(:foo).with(:param_three, :param_four).and_return(:result_two)
|
54
54
|
|
55
55
|
o = Object.new
|
56
56
|
expect(o.foo(:param_one, :param_two)).to eq(:result_one)
|
@@ -112,21 +112,21 @@ Feature: stub on any instance of a class
|
|
112
112
|
describe "stubbing a chain of methods" do
|
113
113
|
context "given symbols representing methods" do
|
114
114
|
it "returns the correct value" do
|
115
|
-
Object.
|
115
|
+
allow_any_instance_of(Object).to receive_message_chain(:one, :two, :three).and_return(:four)
|
116
116
|
expect(Object.new.one.two.three).to eq(:four)
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
120
|
context "given a hash at the end" do
|
121
121
|
it "returns the correct value" do
|
122
|
-
Object.
|
122
|
+
allow_any_instance_of(Object).to receive_message_chain(:one, :two, :three=> :four)
|
123
123
|
expect(Object.new.one.two.three).to eq(:four)
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
127
|
context "given a string of methods separated by dots" do
|
128
128
|
it "returns the correct value" do
|
129
|
-
Object.
|
129
|
+
allow_any_instance_of(Object).to receive_message_chain("one.two.three").and_return(:four)
|
130
130
|
expect(Object.new.one.two.three).to eq(:four)
|
131
131
|
end
|
132
132
|
end
|
@@ -27,21 +27,21 @@ Feature: stub a chain of methods
|
|
27
27
|
|
28
28
|
context "given symbols representing methods" do
|
29
29
|
it "returns the correct value" do
|
30
|
-
subject.
|
30
|
+
allow(subject).to receive_message_chain(:one, :two, :three).and_return(:four)
|
31
31
|
expect(subject.one.two.three).to eq(:four)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
context "given a hash at the end" do
|
36
36
|
it "returns the correct value" do
|
37
|
-
subject.
|
37
|
+
allow(subject).to receive_message_chain(:one, :two, :three => :four)
|
38
38
|
expect(subject.one.two.three).to eq(:four)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
context "given a string of methods separated by dots" do
|
43
43
|
it "returns the correct value" do
|
44
|
-
subject.
|
44
|
+
allow(subject).to receive_message_chain("one.two.three").and_return(:four)
|
45
45
|
expect(subject.one.two.three).to eq(:four)
|
46
46
|
end
|
47
47
|
end
|
@@ -18,7 +18,7 @@ Feature: double handling to_ary
|
|
18
18
|
describe "#to_ary" do
|
19
19
|
shared_examples "to_ary" do
|
20
20
|
it "can be overridden with a stub" do
|
21
|
-
obj.
|
21
|
+
allow(obj).to receive(:to_ary) { :non_nil_value }
|
22
22
|
expect(obj.to_ary).to be(:non_nil_value)
|
23
23
|
end
|
24
24
|
|
@@ -66,7 +66,7 @@ Feature: Spy on a stubbed method on a pure mock
|
|
66
66
|
Given a file named "spy_message_spec.rb" with:
|
67
67
|
"""ruby
|
68
68
|
describe "have_received" do
|
69
|
-
|
69
|
+
subject(:invitation) { double('invitation', :deliver => true) }
|
70
70
|
before { invitation.deliver }
|
71
71
|
|
72
72
|
it { should have_received(:deliver) }
|
@@ -13,31 +13,42 @@ Feature: Test::Unit integration
|
|
13
13
|
require 'rspec/mocks'
|
14
14
|
|
15
15
|
class RSpecMocksTest < Test::Unit::TestCase
|
16
|
+
include RSpec::Mocks::ExampleMethods
|
17
|
+
|
16
18
|
def setup
|
17
|
-
RSpec::Mocks.setup
|
18
|
-
|
19
|
+
RSpec::Mocks.setup
|
20
|
+
end
|
21
|
+
|
22
|
+
def teardown
|
23
|
+
RSpec::Mocks.verify
|
24
|
+
ensure
|
25
|
+
RSpec::Mocks.teardown
|
19
26
|
end
|
20
27
|
|
21
|
-
def
|
28
|
+
def test_passing_positive_expectation
|
22
29
|
obj = Object.new
|
23
30
|
expect(obj).to receive(:message)
|
24
31
|
obj.message
|
25
32
|
end
|
26
33
|
|
27
|
-
def
|
34
|
+
def test_failing_positive_expectation
|
28
35
|
obj = Object.new
|
29
|
-
expect(obj).
|
36
|
+
expect(obj).to receive(:message)
|
30
37
|
obj.message
|
31
38
|
end
|
32
39
|
|
33
|
-
def
|
40
|
+
def test_passing_negative_expectation
|
34
41
|
obj = Object.new
|
35
|
-
obj.
|
36
|
-
|
42
|
+
expect(obj).to_not receive(:message)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_failing_negative_expectation
|
46
|
+
obj = Object.new
|
47
|
+
expect(obj).to_not receive(:message)
|
48
|
+
obj.message
|
37
49
|
end
|
38
50
|
end
|
39
51
|
"""
|
40
52
|
When I run `ruby rspec_mocks_test.rb`
|
41
|
-
Then the output should contain "
|
53
|
+
Then the output should contain "4 tests, 0 assertions, 0 failures, 1 errors" or "4 tests, 0 assertions, 1 failures, 0 errors"
|
42
54
|
And the output should contain "expected: 0 times with any arguments"
|
43
|
-
And the output should contain "old_message is deprecated"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
## Verifying Doubles
|
2
|
+
|
3
|
+
Verifying doubles are a stricter alternative to normal doubles that provide
|
4
|
+
guarantees about what is being verified. When using verifying doubles, RSpec
|
5
|
+
will check that the methods being stubbed are actually present on the
|
6
|
+
underlying object if it is available. Prefer using veryifing doubles over
|
7
|
+
normal doubles.
|
8
|
+
|
9
|
+
No checking will happen if the underlying object or class is not defined, but
|
10
|
+
when run with it present (either as a full spec run or by explicitly preloading
|
11
|
+
collaborators) a failure will be triggered if an invalid method is being
|
12
|
+
stubbed or a method is called with an invalid number of arguments.
|
13
|
+
|
14
|
+
This dual approach allows you to move very quickly and test components in
|
15
|
+
isolation, while giving you confidence that your doubles are not a complete
|
16
|
+
fiction. Testing in isolation is optional but recommend for classes that do not
|
17
|
+
depend on third-party components.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Using a class double
|
2
2
|
|
3
3
|
`class_double` is provided as a complement to `instance_double`, with the
|
4
|
-
difference that it verifies
|
4
|
+
difference that it verifies _class_ methods on the given class rather than
|
5
5
|
instance methods.
|
6
6
|
|
7
7
|
In addition, it also provides a convenience method `as_stubbed_const` to
|
@@ -71,18 +71,3 @@ Feature: Using a class double
|
|
71
71
|
When I run `rspec spec/user_spec.rb`
|
72
72
|
Then the output should contain "1 example, 1 failure"
|
73
73
|
And the output should contain "ConsoleNotifier does not implement:"
|
74
|
-
|
75
|
-
Scenario: adding `color` as a second argument to `ConsoleNotifier.notify`
|
76
|
-
Given a file named "lib/console_notifier.rb" with:
|
77
|
-
"""ruby
|
78
|
-
class ConsoleNotifier
|
79
|
-
MAX_WIDTH = 80
|
80
|
-
|
81
|
-
def self.notify(message, color)
|
82
|
-
puts color + message
|
83
|
-
end
|
84
|
-
end
|
85
|
-
"""
|
86
|
-
When I run `rspec spec/user_spec.rb`
|
87
|
-
Then the output should contain "1 example, 1 failure"
|
88
|
-
And the output should contain "Wrong number of arguments."
|
@@ -1,20 +1,13 @@
|
|
1
|
-
Feature:
|
1
|
+
Feature: Using an instance double
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
An `instance_double` is the most common type of verifying double. It takes a
|
4
|
+
class name or object as its first argument, then verifies that any methods
|
5
|
+
being stubbed would be present on an _instance_ of that class. If any
|
6
|
+
argument matchers are specified, it also verifies that the number of
|
7
|
+
arguments is correct.
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
preloading collaborators) a failure will be triggered if an invalid method is
|
12
|
-
being stubbed.
|
13
|
-
|
14
|
-
This dual approach allows you to move very quickly and test components in
|
15
|
-
isolation, while giving you confidence that your doubles are not a complete
|
16
|
-
fiction. Testing in isolation is optional but recommend for classes that do
|
17
|
-
not depend on third-party components.
|
9
|
+
For methods handled by `method_missing`, see [dynamic
|
10
|
+
objects](./dynamic-objects).
|
18
11
|
|
19
12
|
Background:
|
20
13
|
Given a file named "app/models/user.rb" with:
|
@@ -26,13 +19,6 @@ Feature: Verifying doubles
|
|
26
19
|
end
|
27
20
|
"""
|
28
21
|
|
29
|
-
Given a file named "app/models/console_notifier.rb" with:
|
30
|
-
"""ruby
|
31
|
-
class ConsoleNotifier
|
32
|
-
# notify is not defined yet.
|
33
|
-
end
|
34
|
-
"""
|
35
|
-
|
36
22
|
Given a file named "spec/unit_helper.rb" with:
|
37
23
|
"""ruby
|
38
24
|
$LOAD_PATH.unshift("app/models")
|
@@ -80,6 +66,38 @@ Feature: Verifying doubles
|
|
80
66
|
When I run `rspec spec/unit/user_spec.rb`
|
81
67
|
Then the examples should all pass
|
82
68
|
|
83
|
-
Scenario: spec
|
69
|
+
Scenario: spec passes with dependencies loaded and method implemented
|
70
|
+
Given a file named "app/models/console_notifier.rb" with:
|
71
|
+
"""ruby
|
72
|
+
class ConsoleNotifier
|
73
|
+
def notify(msg)
|
74
|
+
puts message
|
75
|
+
end
|
76
|
+
end
|
77
|
+
"""
|
78
|
+
|
79
|
+
When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
|
80
|
+
Then the examples should all pass
|
81
|
+
|
82
|
+
Scenario: spec fails with dependencies loaded and method unimplemented
|
83
|
+
Given a file named "app/models/console_notifier.rb" with:
|
84
|
+
"""ruby
|
85
|
+
class ConsoleNotifier
|
86
|
+
end
|
87
|
+
"""
|
88
|
+
When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
|
89
|
+
Then the output should contain "1 example, 1 failure"
|
90
|
+
And the output should contain "ConsoleNotifier does not implement:"
|
91
|
+
|
92
|
+
Scenario: spec fails with dependencies loaded and incorrect arity
|
93
|
+
Given a file named "app/models/console_notifier.rb" with:
|
94
|
+
"""ruby
|
95
|
+
class ConsoleNotifier
|
96
|
+
def notify(msg, color)
|
97
|
+
puts color + message
|
98
|
+
end
|
99
|
+
end
|
100
|
+
"""
|
84
101
|
When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
|
85
102
|
Then the output should contain "1 example, 1 failure"
|
103
|
+
And the output should contain "Wrong number of arguments."
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Partial doubles
|
2
2
|
|
3
|
-
When the `verify_partial_doubles` configuration option is set, the same
|
4
|
-
and method
|
3
|
+
When the `verify_partial_doubles` configuration option is set, the same argument
|
4
|
+
and method existence checks that are performed for `object_double` are also
|
5
5
|
performed on partial doubles. You should set this unless you have a good
|
6
6
|
reason not to. It defaults to off only for backwards compatibility.
|
7
7
|
|
data/lib/rspec/mocks.rb
CHANGED
@@ -1,100 +1,87 @@
|
|
1
1
|
require 'rspec/mocks/framework'
|
2
2
|
require 'rspec/mocks/version'
|
3
|
+
require 'rspec/support'
|
3
4
|
|
4
5
|
module RSpec
|
5
|
-
|
6
|
+
# Contains top-level utility methods. While this contains a few
|
7
|
+
# public methods, these are not generally meant to be called from
|
8
|
+
# a test or example. They exist primarily for integration with
|
9
|
+
# test frameworks (such as rspec-core).
|
6
10
|
module Mocks
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
include RSpec::Mocks::ExampleMethods
|
13
|
-
end
|
14
|
-
self.space ||= RSpec::Mocks::Space.new
|
15
|
-
end
|
16
|
-
|
17
|
-
def verify
|
18
|
-
space.verify_all
|
19
|
-
end
|
20
|
-
|
21
|
-
def teardown
|
22
|
-
space.reset_all
|
23
|
-
end
|
24
|
-
|
25
|
-
def proxy_for(object)
|
26
|
-
space.proxy_for(object)
|
27
|
-
end
|
11
|
+
# Performs per-test/example setup. This should be called before
|
12
|
+
# an test or example begins.
|
13
|
+
def self.setup
|
14
|
+
@space_stack << (@space = space.new_scope)
|
15
|
+
end
|
28
16
|
|
29
|
-
|
30
|
-
|
31
|
-
|
17
|
+
# Verifies any message expectations that were set during the
|
18
|
+
# test or example. This should be called at the end of an example.
|
19
|
+
def self.verify
|
20
|
+
space.verify_all
|
21
|
+
end
|
32
22
|
|
33
|
-
|
34
|
-
|
35
|
-
|
23
|
+
# Cleans up all test double state (including any methods that were
|
24
|
+
# redefined on partial doubles). This _must_ be called after
|
25
|
+
# each example, even if an error was raised during the example.
|
26
|
+
def self.teardown
|
27
|
+
space.reset_all
|
28
|
+
@space_stack.pop
|
29
|
+
@space = @space_stack.last || @root_space
|
30
|
+
end
|
36
31
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
32
|
+
# Adds an allowance (stub) on `subject`
|
33
|
+
#
|
34
|
+
# @param subject the subject to which the message will be added
|
35
|
+
# @param message a symbol, representing the message that will be
|
36
|
+
# added.
|
37
|
+
# @param opts a hash of options, :expected_from is used to set the
|
38
|
+
# original call site
|
39
|
+
# @param block an optional implementation for the allowance
|
40
|
+
#
|
41
|
+
# @example Defines the implementation of `foo` on `bar`, using the passed block
|
42
|
+
# x = 0
|
43
|
+
# RSpec::Mocks.allow_message(bar, :foo) { x += 1 }
|
44
|
+
def self.allow_message(subject, message, opts={}, &block)
|
45
|
+
orig_caller = opts.fetch(:expected_from) {
|
46
|
+
CallerFilter.first_non_rspec_line
|
47
|
+
}
|
48
|
+
space.proxy_for(subject).add_stub(orig_caller, message, opts, &block)
|
49
|
+
end
|
56
50
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
51
|
+
# Sets a message expectation on `subject`.
|
52
|
+
# @param subject the subject on which the message will be expected
|
53
|
+
# @param message a symbol, representing the message that will be
|
54
|
+
# expected.
|
55
|
+
# @param opts a hash of options, :expected_from is used to set the
|
56
|
+
# original call site
|
57
|
+
# @param block an optional implementation for the expectation
|
58
|
+
#
|
59
|
+
# @example Expect the message `foo` to receive `bar`, then call it
|
60
|
+
# RSpec::Mocks.expect_message(bar, :foo)
|
61
|
+
# bar.foo
|
62
|
+
def self.expect_message(subject, message, opts={}, &block)
|
63
|
+
orig_caller = opts.fetch(:expected_from) {
|
64
|
+
CallerFilter.first_non_rspec_line
|
65
|
+
}
|
66
|
+
space.proxy_for(subject).add_message_expectation(orig_caller, message, opts, &block)
|
67
|
+
end
|
75
68
|
|
76
|
-
|
77
|
-
|
69
|
+
def self.with_temporary_scope
|
70
|
+
setup
|
78
71
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
#
|
85
|
-
# - Objects that redefine #method (e.g. an HTTPRequest struct)
|
86
|
-
# - BasicObject subclasses that mixin a Kernel dup (e.g. SimpleDelegator)
|
87
|
-
def method_handle_for(object, method_name)
|
88
|
-
if ::Kernel === object
|
89
|
-
KERNEL_METHOD_METHOD.bind(object).call(method_name)
|
90
|
-
else
|
91
|
-
object.method(method_name)
|
92
|
-
end
|
72
|
+
begin
|
73
|
+
yield
|
74
|
+
verify
|
75
|
+
ensure
|
76
|
+
teardown
|
93
77
|
end
|
94
78
|
end
|
95
79
|
|
80
|
+
class << self; attr_reader :space; end
|
81
|
+
@space_stack = []
|
82
|
+
@root_space = @space = RSpec::Mocks::RootSpace.new
|
83
|
+
|
96
84
|
# @private
|
97
85
|
IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored'
|
98
86
|
end
|
99
87
|
end
|
100
|
-
|