rspec-mocks 2.7.0.rc1 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +0 -19
- data/lib/rspec/mocks.rb +12 -13
- data/lib/rspec/mocks/any_instance/recorder.rb +12 -6
- data/lib/rspec/mocks/argument_matchers.rb +19 -25
- data/lib/rspec/mocks/message_expectation.rb +7 -4
- data/lib/rspec/mocks/methods.rb +5 -7
- data/lib/rspec/mocks/proxy.rb +3 -3
- data/lib/rspec/mocks/version.rb +4 -4
- data/spec/rspec/mocks/any_instance_spec.rb +73 -23
- metadata +10 -14
data/README.md
CHANGED
@@ -3,21 +3,6 @@
|
|
3
3
|
rspec-mocks provides a test-double framework for rspec including support
|
4
4
|
for method stubs, fakes, and message expectations.
|
5
5
|
|
6
|
-
[](http://travis-ci.org/rspec/rspec-mocks)
|
7
|
-
|
8
|
-
## Documentation
|
9
|
-
|
10
|
-
The [Cucumber features](http://relishapp.com/rspec/rspec-mocks) are the
|
11
|
-
most comprehensive and up-to-date docs for end-users.
|
12
|
-
|
13
|
-
The [RDoc](http://rubydoc.info/gems/rspec-mocks/2.3.0/frames) provides additional
|
14
|
-
information for contributors and/or extenders.
|
15
|
-
|
16
|
-
All of the documentation is open source and a work in progress. If you find it
|
17
|
-
lacking or confusing, you can help improve it by submitting requests and
|
18
|
-
patches to the [rspec-mocks issue
|
19
|
-
tracker](https://github.com/rspec/rspec-mocks/issues).
|
20
|
-
|
21
6
|
## Install
|
22
7
|
|
23
8
|
gem install rspec # for rspec-core, rspec-expectations, rspec-mocks
|
@@ -48,10 +33,6 @@ tracker](https://github.com/rspec/rspec-mocks/issues).
|
|
48
33
|
end
|
49
34
|
end
|
50
35
|
|
51
|
-
## Contribute
|
52
|
-
|
53
|
-
See [http://github.com/rspec/rspec-dev](http://github.com/rspec/rspec-dev)
|
54
|
-
|
55
36
|
## Also see
|
56
37
|
|
57
38
|
* [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
|
data/lib/rspec/mocks.rb
CHANGED
@@ -17,7 +17,7 @@ module RSpec
|
|
17
17
|
#
|
18
18
|
# book = double("book")
|
19
19
|
# double.stub(:title) { "The RSpec Book" }
|
20
|
-
# double.title => "The RSpec Book"
|
20
|
+
# double.title # => "The RSpec Book"
|
21
21
|
#
|
22
22
|
# When we declare a stub, we say we are "stubbing" a method.
|
23
23
|
#
|
@@ -37,9 +37,9 @@ module RSpec
|
|
37
37
|
# == Mock Objects and Test Stubs
|
38
38
|
#
|
39
39
|
# The names Mock Object and Test Stub suggest specialized Test Doubles. i.e.
|
40
|
-
# Test Stub
|
41
|
-
# Object
|
42
|
-
#
|
40
|
+
# a Test Stub is a Test Double that only supports method stubs, and a Mock
|
41
|
+
# Object is a Test Double that supports message expectations and method
|
42
|
+
# stubs.
|
43
43
|
#
|
44
44
|
# There is a lot of overlapping nomenclature here, and there are many
|
45
45
|
# variations of these patterns (fakes, spies, etc). Keep in mind that most of
|
@@ -60,7 +60,7 @@ module RSpec
|
|
60
60
|
#
|
61
61
|
# In this case we're instrumenting Person to return the person object we've
|
62
62
|
# defined whenever it receives the +find+ message. We can do this with any
|
63
|
-
# object in a system because
|
63
|
+
# object in a system because rspec-mocks adds the +stub+ and +should_receive+
|
64
64
|
# methods to every object. When we use either, RSpec replaces the method
|
65
65
|
# we're stubbing or mocking with it's own test-double-like method. At the
|
66
66
|
# end of the example, RSpec verifies any message expectations, and then
|
@@ -73,15 +73,14 @@ module RSpec
|
|
73
73
|
#
|
74
74
|
# == Argument Matchers
|
75
75
|
#
|
76
|
-
# Arguments that are passed to
|
77
|
-
# using
|
78
|
-
# rather than the arguments themselves, you can use any of
|
79
|
-
# They don't all make syntactic
|
80
|
-
#
|
76
|
+
# Arguments that are passed to +with+ are compared with actual arguments
|
77
|
+
# received using ==. In cases in which you want to specify things about the
|
78
|
+
# arguments rather than the arguments themselves, you can use any of the
|
79
|
+
# matchers that ship with rspec-expectations. They don't all make syntactic
|
80
|
+
# sense (they were primarily designed for use with RSpec::Expectations), but
|
81
|
+
# you are free to create your own custom RSpec::Matchers.
|
81
82
|
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
# In addition, RSpec::Mocks adds some keyword Symbols that you can use to
|
83
|
+
# rspec-mocks also adds some keyword Symbols that you can use to
|
85
84
|
# specify certain kinds of arguments:
|
86
85
|
#
|
87
86
|
# double.should_receive(:msg).with(no_args())
|
@@ -36,6 +36,10 @@ module RSpec
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def stub!(*)
|
40
|
+
raise "stub! is not supported on any_instance. Use stub instead."
|
41
|
+
end
|
42
|
+
|
39
43
|
def stub_chain(method_name_or_string_chain, *args, &block)
|
40
44
|
if period_separated_method_chain?(method_name_or_string_chain)
|
41
45
|
first_method_name = method_name_or_string_chain.split('.').first.to_sym
|
@@ -89,7 +93,7 @@ module RSpec
|
|
89
93
|
end
|
90
94
|
|
91
95
|
def restore_method!(method_name)
|
92
|
-
if
|
96
|
+
if public_protected_or_private_method_defined?(build_alias_method_name(method_name))
|
93
97
|
restore_original_method!(method_name)
|
94
98
|
else
|
95
99
|
remove_dummy_method!(method_name)
|
@@ -118,12 +122,14 @@ module RSpec
|
|
118
122
|
def backup_method!(method_name)
|
119
123
|
alias_method_name = build_alias_method_name(method_name)
|
120
124
|
@klass.class_eval do
|
121
|
-
|
122
|
-
|
123
|
-
end
|
124
|
-
end
|
125
|
+
alias_method alias_method_name, method_name
|
126
|
+
end if public_protected_or_private_method_defined?(method_name)
|
125
127
|
end
|
126
|
-
|
128
|
+
|
129
|
+
def public_protected_or_private_method_defined?(method_name)
|
130
|
+
@klass.method_defined?(method_name) || @klass.private_method_defined?(method_name)
|
131
|
+
end
|
132
|
+
|
127
133
|
def stop_observing!(method_name)
|
128
134
|
restore_method!(method_name)
|
129
135
|
@observed_methods.delete(method_name)
|
@@ -138,48 +138,41 @@ module RSpec
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
-
# :call-seq:
|
142
|
-
# object.should_receive(:message).with(any_args())
|
143
|
-
#
|
144
141
|
# Passes if object receives :message with any args at all. This is
|
145
142
|
# really a more explicit variation of object.should_receive(:message)
|
143
|
+
#
|
144
|
+
# == Examples
|
145
|
+
# object.should_receive(:message).with(any_args())
|
146
146
|
def any_args
|
147
147
|
AnyArgsMatcher.new
|
148
148
|
end
|
149
149
|
|
150
|
-
# :call-seq:
|
151
|
-
# object.should_receive(:message).with(anything())
|
152
|
-
#
|
153
150
|
# Passes as long as there is an argument.
|
151
|
+
#
|
152
|
+
# == Examples
|
153
|
+
# object.should_receive(:message).with(anything())
|
154
154
|
def anything
|
155
155
|
AnyArgMatcher.new(nil)
|
156
156
|
end
|
157
157
|
|
158
|
-
# :call-seq:
|
159
|
-
# object.should_receive(:message).with(no_args)
|
160
|
-
#
|
161
158
|
# Passes if no arguments are passed along with the message
|
159
|
+
#
|
160
|
+
# == Examples
|
161
|
+
# object.should_receive(:message).with(no_args)
|
162
162
|
def no_args
|
163
163
|
NoArgsMatcher.new
|
164
164
|
end
|
165
165
|
|
166
|
-
# :call-seq:
|
167
|
-
# object.should_receive(:message).with(duck_type(:hello))
|
168
|
-
# object.should_receive(:message).with(duck_type(:hello, :goodbye))
|
169
|
-
#
|
170
166
|
# Passes if the argument responds to the specified messages.
|
171
167
|
#
|
172
168
|
# == Examples
|
173
|
-
#
|
174
|
-
#
|
175
|
-
# display = double('display')
|
176
|
-
# display.should_receive(:present_names).with(duck_type(:length, :each))
|
177
|
-
# => passes
|
169
|
+
# object.should_receive(:message).with(duck_type(:hello))
|
170
|
+
# object.should_receive(:message).with(duck_type(:hello, :goodbye))
|
178
171
|
def duck_type(*args)
|
179
172
|
DuckTypeMatcher.new(*args)
|
180
173
|
end
|
181
174
|
|
182
|
-
#
|
175
|
+
# == Examples
|
183
176
|
# object.should_receive(:message).with(boolean())
|
184
177
|
#
|
185
178
|
# Passes if the argument is boolean.
|
@@ -187,22 +180,23 @@ module RSpec
|
|
187
180
|
BooleanMatcher.new(nil)
|
188
181
|
end
|
189
182
|
|
190
|
-
#
|
183
|
+
# Passes if the argument is a hash that includes the specified key(s) or key/value
|
184
|
+
# pairs. If the hash includes other keys, it will still pass.
|
185
|
+
#
|
186
|
+
# == Examples
|
191
187
|
# object.should_receive(:message).with(hash_including(:key => val))
|
192
188
|
# object.should_receive(:message).with(hash_including(:key))
|
193
189
|
# object.should_receive(:message).with(hash_including(:key, :key2 => val2))
|
194
|
-
# Passes if the argument is a hash that includes the specified key(s) or key/value
|
195
|
-
# pairs. If the hash includes other keys, it will still pass.
|
196
190
|
def hash_including(*args)
|
197
191
|
HashIncludingMatcher.new(anythingize_lonely_keys(*args))
|
198
192
|
end
|
199
193
|
|
200
|
-
#
|
194
|
+
# Passes if the argument is a hash that doesn't include the specified key(s) or key/value
|
195
|
+
#
|
196
|
+
# == Examples
|
201
197
|
# object.should_receive(:message).with(hash_not_including(:key => val))
|
202
198
|
# object.should_receive(:message).with(hash_not_including(:key))
|
203
199
|
# object.should_receive(:message).with(hash_not_including(:key, :key2 => :val2))
|
204
|
-
#
|
205
|
-
# Passes if the argument is a hash that doesn't include the specified key(s) or key/value
|
206
200
|
def hash_not_including(*args)
|
207
201
|
HashNotIncludingMatcher.new(anythingize_lonely_keys(*args))
|
208
202
|
end
|
@@ -63,10 +63,8 @@ module RSpec
|
|
63
63
|
@return_block = block_given? ? return_block : lambda { value }
|
64
64
|
end
|
65
65
|
|
66
|
-
#
|
67
|
-
#
|
68
|
-
# and_raise(Exception) #any exception class
|
69
|
-
# and_raise(exception) #any exception object
|
66
|
+
# Tells the mock or stub to raise an exception when the message
|
67
|
+
# is received.
|
70
68
|
#
|
71
69
|
# == Warning
|
72
70
|
#
|
@@ -74,6 +72,11 @@ module RSpec
|
|
74
72
|
# raise an instance of it, creating it with +new+. If the exception
|
75
73
|
# class initializer requires any parameters, you must pass in an
|
76
74
|
# instance and not the class.
|
75
|
+
#
|
76
|
+
# == Examples
|
77
|
+
# and_raise()
|
78
|
+
# and_raise(Exception) #any exception class
|
79
|
+
# and_raise(exception) #any exception object
|
77
80
|
def and_raise(exception=Exception)
|
78
81
|
@exception_to_raise = exception
|
79
82
|
end
|
data/lib/rspec/mocks/methods.rb
CHANGED
@@ -24,15 +24,13 @@ module RSpec
|
|
24
24
|
alias_method :stub!, :stub
|
25
25
|
alias_method :unstub!, :unstub
|
26
26
|
|
27
|
-
# :call-seq:
|
28
|
-
# double.stub_chain("foo.bar") { :baz }
|
29
|
-
# double.stub_chain(:foo, :bar) { :baz }
|
30
|
-
#
|
31
27
|
# Stubs a chain of methods. Especially useful with fluent and/or
|
32
28
|
# composable interfaces.
|
33
29
|
#
|
34
30
|
# == Examples
|
35
31
|
#
|
32
|
+
# double.stub_chain("foo.bar") { :baz }
|
33
|
+
# double.stub_chain(:foo, :bar) { :baz }
|
36
34
|
# Article.stub_chain("recent.published") { [Article.new] }
|
37
35
|
def stub_chain(*chain, &blk)
|
38
36
|
chain, blk = format_chain(*chain, &blk)
|
@@ -50,15 +48,15 @@ module RSpec
|
|
50
48
|
end
|
51
49
|
end
|
52
50
|
|
53
|
-
def received_message?(sym, *args, &block)
|
51
|
+
def received_message?(sym, *args, &block)
|
54
52
|
__mock_proxy.received_message?(sym.to_sym, *args, &block)
|
55
53
|
end
|
56
54
|
|
57
|
-
def rspec_verify
|
55
|
+
def rspec_verify
|
58
56
|
__mock_proxy.verify
|
59
57
|
end
|
60
58
|
|
61
|
-
def rspec_reset
|
59
|
+
def rspec_reset
|
62
60
|
__mock_proxy.reset
|
63
61
|
end
|
64
62
|
|
data/lib/rspec/mocks/proxy.rb
CHANGED
@@ -45,11 +45,11 @@ module RSpec
|
|
45
45
|
@object
|
46
46
|
end
|
47
47
|
|
48
|
-
def already_proxied_respond_to
|
48
|
+
def already_proxied_respond_to
|
49
49
|
@already_proxied_respond_to = true
|
50
50
|
end
|
51
51
|
|
52
|
-
def already_proxied_respond_to?
|
52
|
+
def already_proxied_respond_to?
|
53
53
|
@already_proxied_respond_to
|
54
54
|
end
|
55
55
|
|
@@ -69,7 +69,7 @@ module RSpec
|
|
69
69
|
method_double[method_name].remove_stub
|
70
70
|
end
|
71
71
|
|
72
|
-
def verify
|
72
|
+
def verify
|
73
73
|
method_doubles.each {|d| d.verify}
|
74
74
|
ensure
|
75
75
|
reset
|
data/lib/rspec/mocks/version.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
3
|
module RSpec
|
@@ -11,6 +10,8 @@ module RSpec
|
|
11
10
|
def existing_method; :existing_method_return_value; end
|
12
11
|
def existing_method_with_arguments(arg_one, arg_two = nil); :existing_method_with_arguments_return_value; end
|
13
12
|
def another_existing_method; end
|
13
|
+
private
|
14
|
+
def private_method; :private_method_return_value; end
|
14
15
|
end
|
15
16
|
end
|
16
17
|
let(:existing_method_return_value){ :existing_method_return_value }
|
@@ -195,7 +196,7 @@ module RSpec
|
|
195
196
|
klass.new.foo.should eq(klass.new.foo)
|
196
197
|
end
|
197
198
|
end
|
198
|
-
|
199
|
+
|
199
200
|
context "core ruby objects" do
|
200
201
|
it "works uniformly across *everything*" do
|
201
202
|
Object.any_instance.stub(:foo).and_return(1)
|
@@ -235,6 +236,14 @@ module RSpec
|
|
235
236
|
end
|
236
237
|
end
|
237
238
|
end
|
239
|
+
|
240
|
+
context "with #stub!" do
|
241
|
+
it "raises with a message instructing the user to use stub instead" do
|
242
|
+
expect do
|
243
|
+
klass.any_instance.stub!(:foo)
|
244
|
+
end.to raise_error(/Use stub instead/)
|
245
|
+
end
|
246
|
+
end
|
238
247
|
|
239
248
|
context "unstub implementation" do
|
240
249
|
it "replaces the stubbed method with the original method" do
|
@@ -635,39 +644,80 @@ module RSpec
|
|
635
644
|
end
|
636
645
|
|
637
646
|
context "with stubbing" do
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
647
|
+
context "public methods" do
|
648
|
+
before(:each) do
|
649
|
+
klass.any_instance.stub(:existing_method).and_return(1)
|
650
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_true
|
651
|
+
end
|
642
652
|
|
643
|
-
|
644
|
-
|
653
|
+
it "restores the class to its original state after each example when no instance is created" do
|
654
|
+
space.verify_all
|
645
655
|
|
646
|
-
|
647
|
-
|
648
|
-
|
656
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
|
657
|
+
klass.new.existing_method.should eq(existing_method_return_value)
|
658
|
+
end
|
649
659
|
|
650
|
-
|
651
|
-
|
660
|
+
it "restores the class to its original state after each example when one instance is created" do
|
661
|
+
klass.new.existing_method
|
652
662
|
|
653
|
-
|
663
|
+
space.verify_all
|
654
664
|
|
655
|
-
|
656
|
-
|
657
|
-
|
665
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
|
666
|
+
klass.new.existing_method.should eq(existing_method_return_value)
|
667
|
+
end
|
658
668
|
|
659
|
-
|
660
|
-
|
661
|
-
|
669
|
+
it "restores the class to its original state after each example when more than one instance is created" do
|
670
|
+
klass.new.existing_method
|
671
|
+
klass.new.existing_method
|
662
672
|
|
663
|
-
|
673
|
+
space.verify_all
|
664
674
|
|
665
|
-
|
666
|
-
|
675
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
|
676
|
+
klass.new.existing_method.should eq(existing_method_return_value)
|
677
|
+
end
|
678
|
+
end
|
679
|
+
|
680
|
+
context "private methods" do
|
681
|
+
before :each do
|
682
|
+
klass.any_instance.stub(:private_method).and_return(:something)
|
683
|
+
space.verify_all
|
684
|
+
end
|
685
|
+
|
686
|
+
it "cleans up the backed up method" do
|
687
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
|
688
|
+
end
|
689
|
+
|
690
|
+
it "restores a stubbed private method after the spec is run" do
|
691
|
+
klass.private_method_defined?(:private_method).should be_true
|
692
|
+
end
|
693
|
+
|
694
|
+
it "ensures that the restored method behaves as it originally did" do
|
695
|
+
klass.new.send(:private_method).should eq(:private_method_return_value)
|
696
|
+
end
|
667
697
|
end
|
668
698
|
end
|
669
699
|
|
670
700
|
context "with expectations" do
|
701
|
+
context "private methods" do
|
702
|
+
before :each do
|
703
|
+
klass.any_instance.should_receive(:private_method).and_return(:something)
|
704
|
+
klass.new.private_method
|
705
|
+
space.verify_all
|
706
|
+
end
|
707
|
+
|
708
|
+
it "cleans up the backed up method" do
|
709
|
+
klass.method_defined?(:__existing_method_without_any_instance__).should be_false
|
710
|
+
end
|
711
|
+
|
712
|
+
it "restores a stubbed private method after the spec is run" do
|
713
|
+
klass.private_method_defined?(:private_method).should be_true
|
714
|
+
end
|
715
|
+
|
716
|
+
it "ensures that the restored method behaves as it originally did" do
|
717
|
+
klass.new.send(:private_method).should eq(:private_method_return_value)
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
671
721
|
context "ensures that the subsequent specs do not see expectations set in previous specs" do
|
672
722
|
context "when the instance created after the expectation is set" do
|
673
723
|
it "first spec" do
|
metadata
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-mocks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 7
|
9
9
|
- 0
|
10
|
-
|
11
|
-
- 1
|
12
|
-
version: 2.7.0.rc1
|
10
|
+
version: 2.7.0
|
13
11
|
platform: ruby
|
14
12
|
authors:
|
15
13
|
- David Chelimsky
|
@@ -18,7 +16,7 @@ autorequire:
|
|
18
16
|
bindir: bin
|
19
17
|
cert_chain: []
|
20
18
|
|
21
|
-
date: 2011-10-
|
19
|
+
date: 2011-10-16 00:00:00 Z
|
22
20
|
dependencies: []
|
23
21
|
|
24
22
|
description: RSpec's 'test double' framework, with support for stubbing and mocking
|
@@ -147,21 +145,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
146
|
none: false
|
149
147
|
requirements:
|
150
|
-
- - "
|
148
|
+
- - ">="
|
151
149
|
- !ruby/object:Gem::Version
|
152
|
-
hash:
|
150
|
+
hash: 3
|
153
151
|
segments:
|
154
|
-
-
|
155
|
-
|
156
|
-
- 1
|
157
|
-
version: 1.3.1
|
152
|
+
- 0
|
153
|
+
version: "0"
|
158
154
|
requirements: []
|
159
155
|
|
160
156
|
rubyforge_project: rspec
|
161
|
-
rubygems_version: 1.8.
|
157
|
+
rubygems_version: 1.8.11
|
162
158
|
signing_key:
|
163
159
|
specification_version: 3
|
164
|
-
summary: rspec-mocks-2.7.0
|
160
|
+
summary: rspec-mocks-2.7.0
|
165
161
|
test_files:
|
166
162
|
- features/README.markdown
|
167
163
|
- features/Scope.md
|