rspec-mocks 2.5.0 → 2.6.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -0
- data/Gemfile +13 -12
- data/Guardfile +3 -3
- data/README.md +2 -0
- data/features/.nav +4 -0
- data/features/Changelog.md +12 -0
- data/features/README.markdown +44 -4
- data/features/message_expectations/any_instance.feature +19 -0
- data/features/message_expectations/block_local_expectations.feature.pending +2 -2
- data/features/message_expectations/expect_message.feature +3 -3
- data/features/message_expectations/warn_when_expectation_is_set_on_nil.feature +3 -3
- data/features/method_stubs/README.md +32 -24
- data/features/method_stubs/any_instance.feature +23 -0
- data/features/method_stubs/as_null_object.feature +36 -0
- data/features/method_stubs/simple_return_value.feature +2 -2
- data/features/method_stubs/stub_chain.feature +13 -6
- data/features/method_stubs/stub_implementation.feature +1 -1
- data/features/method_stubs/to_ary.feature +45 -0
- data/features/outside_rspec/configuration.feature +3 -3
- data/features/outside_rspec/standalone.feature +2 -2
- data/features/step_definitions/additional_cli_steps.rb +4 -0
- data/features/support/env.rb +5 -1
- data/lib/rspec/mocks.rb +2 -1
- data/lib/rspec/mocks/any_instance.rb +246 -0
- data/lib/rspec/mocks/extensions/psych.rb +23 -0
- data/lib/rspec/mocks/framework.rb +1 -0
- data/lib/rspec/mocks/message_expectation.rb +7 -4
- data/lib/rspec/mocks/methods.rb +1 -1
- data/lib/rspec/mocks/mock.rb +2 -2
- data/lib/rspec/mocks/serialization.rb +5 -3
- data/lib/rspec/mocks/space.rb +1 -1
- data/lib/rspec/mocks/version.rb +1 -1
- data/spec/rspec/mocks/and_yield_spec.rb +3 -3
- data/spec/rspec/mocks/any_instance_spec.rb +578 -0
- data/spec/rspec/mocks/any_number_of_times_spec.rb +22 -28
- data/spec/rspec/mocks/at_least_spec.rb +6 -0
- data/spec/rspec/mocks/at_most_spec.rb +6 -0
- data/spec/rspec/mocks/bug_report_10263_spec.rb +12 -14
- data/spec/rspec/mocks/bug_report_7611_spec.rb +2 -4
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +45 -46
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +1 -2
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +119 -122
- data/spec/rspec/mocks/precise_counts_spec.rb +6 -0
- data/spec/rspec/mocks/serialization_spec.rb +21 -3
- data/spec/rspec/mocks/stub_chain_spec.rb +72 -37
- data/spec/rspec/mocks/stub_spec.rb +64 -61
- data/spec/rspec/mocks/to_ary_spec.rb +31 -0
- metadata +32 -15
- data/spec/rspec/mocks/bug_report_7805_spec.rb +0 -22
- data/spec/rspec/mocks/bug_report_8302_spec.rb +0 -26
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -6,29 +6,31 @@ source "http://rubygems.org"
|
|
6
6
|
if File.exist?(library_path)
|
7
7
|
gem lib, :path => library_path
|
8
8
|
else
|
9
|
-
gem lib
|
9
|
+
gem lib, :git => "git://github.com/rspec/#{lib}.git"
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
### dev dependencies
|
14
14
|
gem "rake", "0.8.7"
|
15
|
-
gem "cucumber", "0.
|
16
|
-
gem "aruba", "
|
17
|
-
gem "rcov", "0.9.9"
|
15
|
+
# gem "cucumber", "~> 0.10.2"
|
16
|
+
# gem "aruba", :git => "git://github.com/aslakhellesoy/aruba"
|
17
|
+
gem "rcov", "0.9.9", :platforms => :mri
|
18
18
|
gem "relish", "0.2.0"
|
19
19
|
gem "guard-rspec", "0.1.9"
|
20
20
|
gem "growl", "1.0.3"
|
21
|
-
gem "
|
21
|
+
gem "nokogiri", "1.4.4"
|
22
22
|
|
23
|
-
|
24
|
-
gem
|
25
|
-
gem "autotest-growl", "~> 0.2.9"
|
23
|
+
platforms :mri_18 do
|
24
|
+
gem 'ruby-debug'
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
gem
|
27
|
+
platforms :mri_19 do
|
28
|
+
gem 'linecache19', '0.5.11' # 0.5.12 cannot install on 1.9.1, and 0.5.11 appears to work with both 1.9.1 & 1.9.2
|
29
|
+
gem 'ruby-debug19'
|
30
|
+
gem 'ruby-debug-base19', RUBY_VERSION == '1.9.1' ? '0.11.23' : '~> 0.11.24'
|
31
|
+
end
|
30
32
|
|
31
|
-
platforms :
|
33
|
+
platforms :mri_18, :mri_19 do
|
32
34
|
gem "rb-fsevent", "~> 0.3.9"
|
33
35
|
gem "ruby-prof", "~> 0.9.2"
|
34
36
|
end
|
@@ -36,4 +38,3 @@ end
|
|
36
38
|
platforms :jruby do
|
37
39
|
gem "jruby-openssl"
|
38
40
|
end
|
39
|
-
|
data/Guardfile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# More info at http://github.com/guard/guard#readme
|
3
3
|
|
4
4
|
guard 'rspec', :version => 2 do
|
5
|
-
watch(
|
6
|
-
watch(
|
7
|
-
watch(
|
5
|
+
watch(/^spec\/(.*)_spec.rb/)
|
6
|
+
watch(/^lib\/(.*)\.rb/) { "spec" }
|
7
|
+
watch(/^spec\/spec_helper.rb/) { "spec" }
|
8
8
|
end
|
data/README.md
CHANGED
@@ -3,6 +3,8 @@
|
|
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
|
+
[![build status](http://travis-ci.org/rspec/rspec-mocks.png)](http://travis-ci.org/rspec/rspec-mocks)
|
7
|
+
|
6
8
|
## Documentation
|
7
9
|
|
8
10
|
The [Cucumber features](http://relishapp.com/rspec/rspec-mocks) are the
|
data/features/.nav
CHANGED
@@ -4,8 +4,12 @@
|
|
4
4
|
- simple_return_value.feature
|
5
5
|
- stub_implementation.feature
|
6
6
|
- stub_chain.feature
|
7
|
+
- any_instance.feature
|
8
|
+
- as_null_object.feature
|
9
|
+
- to_ary.feature
|
7
10
|
- message_expectations:
|
8
11
|
- expect_message.feature
|
12
|
+
- any_instance.feature
|
9
13
|
- block_local_expectations.feature.pending
|
10
14
|
- warn_when_expectation_is_set_on_nil.feature
|
11
15
|
- outside_rspec:
|
data/features/Changelog.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
### 2.6.0.rc2 / 2011-04-18
|
2
|
+
|
3
|
+
[full changelog](http://github.com/rspec/rspec-mocks/compare/v2.5.0...v2.6.1.rc2)
|
4
|
+
|
5
|
+
* Enhancements
|
6
|
+
* Add support for any_instance.stub and any_instance.should_receive (Sidu
|
7
|
+
Ponnappa and Andy Lindeman)
|
8
|
+
|
9
|
+
* Bug fixes
|
10
|
+
* fix bug in which multiple chains with shared messages ending in hashes
|
11
|
+
failed to return the correct value
|
12
|
+
|
1
13
|
### 2.5.0 / 2011-02-05
|
2
14
|
|
3
15
|
[full changelog](http://github.com/rspec/rspec-mocks/compare/v2.4.0...v2.5.0)
|
data/features/README.markdown
CHANGED
@@ -1,10 +1,46 @@
|
|
1
|
-
rspec-mocks
|
2
|
-
|
3
|
-
|
1
|
+
rspec-mocks helps to control the context in a code example by letting you set
|
2
|
+
known return values, fake implementations of methods, and even expectations
|
3
|
+
that specific messages are received by an object.
|
4
|
+
|
5
|
+
You can do these three things on test doubles that rspec-mocks creates for you
|
6
|
+
on the fly, or you can do them on objects that are part of your system.
|
7
|
+
|
8
|
+
## Messages and Methods
|
9
|
+
|
10
|
+
_Message_ and _method_ are metaphors that we use somewhat interchangeably, but
|
11
|
+
they are subtly different. In Object Oriented Programming, objects communicate
|
12
|
+
by sending _messages_ to one another. When an object receives a message, it
|
13
|
+
invokes a _method_ with the same name as the message.
|
14
|
+
|
15
|
+
## Test Doubles
|
16
|
+
|
17
|
+
A test double is an object that stands in for another object in your system
|
18
|
+
during a code example. Use the `double` method to create one:
|
19
|
+
|
20
|
+
double_account = double("Account")
|
21
|
+
|
22
|
+
You can also use the `mock` and `stub` methods to create test doubles, however
|
23
|
+
these methods are there for backward compatibility only and will likely be
|
24
|
+
deprecated and then removed from future versions.
|
25
|
+
|
26
|
+
## Method Stubs
|
27
|
+
|
28
|
+
A method stub is an instruction to an object (real or test double) to return a
|
29
|
+
known value in response to a message:
|
30
|
+
|
31
|
+
die.stub(:roll) { 3 }
|
32
|
+
|
33
|
+
This tells the `die` object to return the value `3` when it receives the `roll`
|
34
|
+
message.
|
35
|
+
|
36
|
+
## Message Expectations
|
37
|
+
|
38
|
+
A message expectation is an expectation that an object should receive a
|
39
|
+
specific message during the course of a code example:
|
4
40
|
|
5
41
|
describe Account do
|
6
42
|
context "when closed" do
|
7
|
-
it "logs an account closed message" do
|
43
|
+
it "logs an 'account closed' message" do
|
8
44
|
logger = double()
|
9
45
|
account = Account.new
|
10
46
|
account.logger = logger
|
@@ -16,6 +52,10 @@ expectations:
|
|
16
52
|
end
|
17
53
|
end
|
18
54
|
|
55
|
+
This example specifies that the `account` object sends the `logger` the
|
56
|
+
`account_closed` message (with itself as an argument) when it receives the
|
57
|
+
`close` message.
|
58
|
+
|
19
59
|
## Issues
|
20
60
|
|
21
61
|
The documentation for rspec-mocks is a work in progress. We'll be adding
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: expect a message on any instance of a class
|
2
|
+
|
3
|
+
Use `any_instance.should_receive` to set an expectation that one (and only
|
4
|
+
one) instance of a class receives a message before the example is completed.
|
5
|
+
|
6
|
+
Scenario: expect a message on any instance of a class
|
7
|
+
Given a file named "example_spec.rb" with:
|
8
|
+
"""
|
9
|
+
describe "any_instance.should_receive" do
|
10
|
+
it "verifies that one instance of the class receives the message" do
|
11
|
+
Object.any_instance.should_receive(:foo).and_return(:return_value)
|
12
|
+
|
13
|
+
o = Object.new
|
14
|
+
o.foo.should eq(:return_value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
"""
|
18
|
+
When I run `rspec example_spec.rb`
|
19
|
+
Then the examples should all pass
|
@@ -30,7 +30,7 @@ Feature: block local expectations
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
"""
|
33
|
-
When I run
|
33
|
+
When I run `rspec spec/account_spec.rb`
|
34
34
|
Then the output should contain "1 example, 0 failures"
|
35
35
|
|
36
36
|
Scenario: failing example
|
@@ -51,5 +51,5 @@ Feature: block local expectations
|
|
51
51
|
end
|
52
52
|
"""
|
53
53
|
|
54
|
-
When I run
|
54
|
+
When I run `rspec spec/account_spec.rb`
|
55
55
|
Then the output should contain "1 example, 1 failure"
|
@@ -32,7 +32,7 @@ Feature: expect a message
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
"""
|
35
|
-
When I run
|
35
|
+
When I run `rspec spec/account_spec.rb`
|
36
36
|
Then the output should contain "1 example, 0 failures"
|
37
37
|
|
38
38
|
Scenario: expect a message with an argument
|
@@ -64,7 +64,7 @@ Feature: expect a message
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
"""
|
67
|
-
When I run
|
67
|
+
When I run `rspec spec/account_spec.rb`
|
68
68
|
Then the output should contain "1 example, 0 failures"
|
69
69
|
|
70
70
|
Scenario: provide a return value
|
@@ -90,5 +90,5 @@ Feature: expect a message
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
"""
|
93
|
-
When I run
|
93
|
+
When I run `rspec message_expectation_spec.rb`
|
94
94
|
Then the output should contain "2 examples, 0 failures"
|
@@ -11,7 +11,7 @@ Feature: warn when expectation is set on nil
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
"""
|
14
|
-
When I run
|
14
|
+
When I run `rspec example_spec.rb`
|
15
15
|
Then the output should contain "An expectation of :foo was set on nil"
|
16
16
|
|
17
17
|
Scenario: allow
|
@@ -26,7 +26,7 @@ Feature: warn when expectation is set on nil
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
"""
|
29
|
-
When I run
|
29
|
+
When I run `rspec example_spec.rb`
|
30
30
|
Then the output should not contain "An expectation"
|
31
31
|
|
32
32
|
Scenario: allow in one example, but not on another
|
@@ -45,6 +45,6 @@ Feature: warn when expectation is set on nil
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
"""
|
48
|
-
When I run
|
48
|
+
When I run `rspec example_spec.rb`
|
49
49
|
Then the output should contain "An expectation of :bar"
|
50
50
|
And the output should not contain "An expectation of :foo"
|
@@ -1,39 +1,47 @@
|
|
1
|
-
###
|
1
|
+
### Stub return values
|
2
2
|
|
3
|
-
|
4
|
-
obj
|
3
|
+
obj.stub(:message).and_return('this is the value to return')
|
4
|
+
obj.stub(:message) { 'this is the value to return' }
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
These two forms are somewhat interchangeable. The difference is that the
|
7
|
+
argument to `and_return` is evaluated immediately, whereas the block contents
|
8
|
+
are evaluated lazily when the `obj` receives the `message` message.
|
8
9
|
|
9
|
-
|
10
|
-
|
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.
|
13
|
+
|
14
|
+
### Fake implementation
|
15
|
+
|
16
|
+
obj.stub(:message) do |arg1, arg2|
|
17
|
+
# set expectations about the args in this block
|
18
|
+
# and/or set a return value
|
19
|
+
end
|
20
|
+
|
21
|
+
### Raising/Throwing
|
22
|
+
|
23
|
+
obj.stub(:message).and_raise("this error")
|
24
|
+
obj.stub(:message).and_throw(:this_symbol)
|
25
|
+
|
26
|
+
You can also use the block format, for consistency with other stubs:
|
27
|
+
|
28
|
+
obj.stub(:message) { raise "this error" }
|
29
|
+
obj.stub(:message) { throw :this_symbol }
|
11
30
|
|
12
31
|
### Argument constraints
|
13
32
|
|
14
33
|
#### Explicit arguments
|
15
34
|
|
16
|
-
obj.stub(:message).with('an argument')
|
17
|
-
obj.stub(:message).with('more_than', 'one_argument')
|
35
|
+
obj.stub(:message).with('an argument') { ... }
|
36
|
+
obj.stub(:message).with('more_than', 'one_argument') { ... }
|
18
37
|
|
19
38
|
#### Argument matchers
|
20
39
|
|
21
|
-
obj.stub(:message).with(anything())
|
22
|
-
obj.stub(:message).with(an_instance_of(Money))
|
23
|
-
obj.stub(:message).with(hash_including(:a => 'b'))
|
40
|
+
obj.stub(:message).with(anything()) { ... }
|
41
|
+
obj.stub(:message).with(an_instance_of(Money)) { ... }
|
42
|
+
obj.stub(:message).with(hash_including(:a => 'b')) { ... }
|
24
43
|
|
25
44
|
#### Regular expressions
|
26
45
|
|
27
|
-
obj.stub(:message).with(/abc/)
|
28
|
-
|
29
|
-
### Raising/Throwing
|
46
|
+
obj.stub(:message).with(/abc/) { ... }
|
30
47
|
|
31
|
-
obj.stub(:message) { raise "this error" }
|
32
|
-
obj.stub(:message) { throw :this_symbol }
|
33
|
-
|
34
|
-
### Arbitrary handling
|
35
|
-
|
36
|
-
obj.stub(:message) do |arg1, arg2|
|
37
|
-
# set expectations about the args in this block
|
38
|
-
# and set a return value
|
39
|
-
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: stub on any instance of a class
|
2
|
+
|
3
|
+
Use `any_instance.stub` on a class to tell any instance of that class to
|
4
|
+
return a value (or values) in response to a given message. If no instance
|
5
|
+
receives the message, nothing happens.
|
6
|
+
|
7
|
+
Messages can be stubbed on any class, including those in Ruby's core library.
|
8
|
+
|
9
|
+
Scenario: simple any_instance stub with a single return value
|
10
|
+
Given a file named "example_spec.rb" with:
|
11
|
+
"""
|
12
|
+
describe "any_instance.stub" do
|
13
|
+
it "returns the specified value on any instance of the class" do
|
14
|
+
Object.any_instance.stub(:foo).and_return(:return_value)
|
15
|
+
|
16
|
+
o = Object.new
|
17
|
+
o.foo.should eq(:return_value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
"""
|
21
|
+
When I run `rspec example_spec.rb`
|
22
|
+
Then the examples should all pass
|
23
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Feature: as_null_object
|
2
|
+
|
3
|
+
Use the `as_null_object` method to ignore any messages that aren't explicitly
|
4
|
+
set as stubs or message expectations.
|
5
|
+
|
6
|
+
EXCEPTION: `to_ary` will raise a NoMethodError unless explicitly stubbed in
|
7
|
+
order to support `flatten` on an Array containing a double.
|
8
|
+
|
9
|
+
Scenario: double acting as_null_object
|
10
|
+
Given a file named "as_null_object_spec.rb" with:
|
11
|
+
"""
|
12
|
+
describe "a double with as_null_object called" do
|
13
|
+
let(:null_object) { double('null object').as_null_object }
|
14
|
+
|
15
|
+
it "responds to any method that is not defined" do
|
16
|
+
null_object.should respond_to(:an_undefined_method)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "allows explicit stubs" do
|
20
|
+
null_object.stub(:foo) { "bar" }
|
21
|
+
null_object.foo.should eq("bar")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "allows explicit expectations" do
|
25
|
+
null_object.should_receive(:something)
|
26
|
+
null_object.something
|
27
|
+
end
|
28
|
+
|
29
|
+
it "supports Array#flatten" do
|
30
|
+
null_object = double('foo')
|
31
|
+
[null_object].flatten.should eq([null_object])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
"""
|
35
|
+
When I run `rspec as_null_object_spec.rb`
|
36
|
+
Then the examples should all pass
|
@@ -20,7 +20,7 @@ Feature: stub with a simple return value
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
"""
|
23
|
-
When I run
|
23
|
+
When I run `rspec example_spec.rb`
|
24
24
|
Then the output should contain "0 failures"
|
25
25
|
|
26
26
|
Scenario: single return value
|
@@ -51,5 +51,5 @@ Feature: stub with a simple return value
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
"""
|
54
|
-
When I run
|
54
|
+
When I run `rspec example_spec.rb`
|
55
55
|
Then the output should contain "0 failures"
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Feature: stub a chain of methods
|
2
2
|
|
3
|
-
|
4
|
-
Method chains are considered a design smell, but it's not really
|
5
|
-
chain that is the problem - it's the dependency chain
|
6
|
-
of messages to different objects:
|
3
|
+
Use the `stub_chain` method to stub a chain of two or more methods in one
|
4
|
+
statement. Method chains are considered a design smell, but it's not really
|
5
|
+
the method chain itself that is the problem - it's the dependency chain
|
6
|
+
represented by a chain of messages to different objects:
|
7
7
|
|
8
8
|
foo.get_bar.get_baz
|
9
9
|
|
@@ -32,6 +32,13 @@ Feature: stub a chain of methods
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
context "given a hash at the end" do
|
36
|
+
it "returns the correct value" do
|
37
|
+
subject.stub_chain(:one, :two, :three => :four)
|
38
|
+
subject.one.two.three.should eq(:four)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
35
42
|
context "given a string of methods separated by dots" do
|
36
43
|
it "returns the correct value" do
|
37
44
|
subject.stub_chain("one.two.three").and_return(:four)
|
@@ -40,5 +47,5 @@ Feature: stub a chain of methods
|
|
40
47
|
end
|
41
48
|
end
|
42
49
|
"""
|
43
|
-
When I run
|
44
|
-
Then the
|
50
|
+
When I run `rspec stub_chain_spec.rb`
|
51
|
+
Then the examples should all pass
|