verified_double 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/CHANGELOG.markdown +8 -0
  2. data/README.md +21 -49
  3. data/features/CHANGELOG.markdown +8 -0
  4. data/features/accessor_method_contracts.feature +107 -0
  5. data/features/customizing_arguments_and_return_values.feature +2 -2
  6. data/features/readme.md +21 -49
  7. data/features/rspec_mock_compatibility.feature +230 -0
  8. data/features/step_definitions/verified_double_steps.rb +17 -0
  9. data/features/{verified_double.feature → verified_mocks.feature} +5 -6
  10. data/features/verified_stubs.feature +94 -0
  11. data/lib/verified_double.rb +25 -10
  12. data/lib/verified_double/matchers.rb +35 -0
  13. data/lib/verified_double/method_signature_value.rb +15 -1
  14. data/lib/verified_double/method_signatures_report.rb +55 -0
  15. data/lib/verified_double/recording_double.rb +33 -12
  16. data/lib/verified_double/relays_to_internal_double_returning_self.rb +12 -0
  17. data/lib/verified_double/version.rb +1 -1
  18. data/spec/spec_helper.rb +3 -4
  19. data/spec/unit_helper.rb +3 -2
  20. data/spec/verified_double/matchers_spec.rb +96 -0
  21. data/spec/verified_double/method_signature_value_spec.rb +35 -0
  22. data/spec/verified_double/method_signatures_report_spec.rb +214 -0
  23. data/spec/verified_double/parse_method_signature_spec.rb +5 -1
  24. data/spec/verified_double/recording_double_spec.rb +103 -30
  25. data/spec/verified_double_spec.rb +70 -7
  26. data/verified_double.gemspec +0 -2
  27. metadata +17 -38
  28. data/lib/verified_double/get_registered_signatures.rb +0 -11
  29. data/lib/verified_double/get_unverified_signatures.rb +0 -13
  30. data/lib/verified_double/get_verified_signatures.rb +0 -17
  31. data/lib/verified_double/output_unverified_signatures.rb +0 -18
  32. data/lib/verified_double/report_unverified_signatures.rb +0 -16
  33. data/lib/verified_double/verify_doubles_service.rb +0 -15
  34. data/spec/verified_double/get_registered_signatures_spec.rb +0 -42
  35. data/spec/verified_double/get_unverified_signatures_spec.rb +0 -52
  36. data/spec/verified_double/get_verified_signatures_spec.rb +0 -63
  37. data/spec/verified_double/output_unverified_signatures_spec.rb +0 -58
  38. data/spec/verified_double/report_unverified_signatures_spec.rb +0 -57
  39. data/spec/verified_double/verify_doubles_service_spec.rb +0 -24
@@ -1,3 +1,11 @@
1
+ 0.1.0 - 2013-06-24
2
+ ------------------
3
+
4
+ * [#3] Pass Scenario: Verifying mocks for accessors.
5
+ * [#3] Pass Scenario: Verifying mocks for readers
6
+ * [#5] Remove rspec-fire dependency.
7
+ * [#5] Use VerifiedDouble to mock and stub doubles in own tests.
8
+
1
9
  0.0.2 - 2013-06-22
2
10
  ------------------
3
11
 
data/README.md CHANGED
@@ -1,65 +1,37 @@
1
1
  # VerifiedDouble
2
2
 
3
- VerifiedDouble would record any mock made in the test suite. It
4
- would then verify if the mock is valid by checking if there is a test
5
- against it.
3
+ [![Build Status](https://travis-ci.org/gsmendoza/verified_double.png)](https://travis-ci.org/gsmendoza/verified_double)
6
4
 
7
- For example, let's say I mocked the save method of a model like so:
5
+ VerifiedDouble verifies mocks made in the test suite by checking if there are tests against them.
6
+
7
+ For example, let's say I mocked the created_at method of a model like this:
8
8
 
9
9
  item = VerifiedDouble.of_instance(Item)
10
- item.should_receive(:save).and_return(true)
10
+ item.should_receive(:created_at).and_return(Time.now)
11
11
 
12
- Calling `VerifiedDouble.of_instance` would record the :save interaction on
13
- item. When running the tests, the gem would look for a test that
14
- confirms if you can indeed call #save on Item. The test should also
15
- ensure that the method indeed returns a boolean value. Since this is hard
16
- to automate, the gem would just look for a test with the tag saying it
17
- verifies that contract:
12
+ The item double records its :created_at call. When
13
+ running the tests, the gem looks for a test that confirms if you can
14
+ indeed call #created_at on Item. The test should also ensure that the method
15
+ returns a Time object. Since this is hard to automate, the gem just looks
16
+ for a test with a tag saying it verifies that contract:
18
17
 
19
- it "tests something", verifies_contract: 'Item#save => Boolean' do
18
+ it "tests something", verifies_contract: 'Item#created_at()=>Time' do
20
19
  #...
21
20
  end
22
21
 
23
- If this test does not exist, the gem would complain that the mock is not
22
+ If this test does not exist, the gem will complain that the mock is not
24
23
  verified.
25
24
 
26
- This is an implementation of [contract tests](http://www.infoq.com/presentations/integration-tests-scam).
27
- Notes about the presentation [here](http://www.beletsky.net/2010/10/agileee-2010-j-b-rainsberger-integrated.html).
28
-
29
- There's already a gem that implements contract tests
30
- ([bogus](https://www.relishapp.com/bogus/bogus/v/0-0-3/docs/contract-tests)).
31
- However, I think there's room for an alternative because:
32
-
33
- 1. It's not clear from the Bogus [documentation](https://www.relishapp.com/bogus/bogus/v/0-0-3/docs/contract-tests/contract-tests-with-mocks)
34
- whether the gem verifies actual arguments/return values or just the types of those
35
- values. While the argument/return types are enough in most cases, sometimes
36
- the actual argument/return values are important. For example, if I mock
37
- Item.where(conditions), the actual conditions are important in
38
- verifying the validity of the where call.
39
-
40
- 2. [By design](https://www.relishapp.com/bogus/bogus/v/0-0-3/docs/fakes/faking-existing-classes#fakes-have-null-object-semantics),
41
- a Bogus fake would return itself to all its methods. I prefer rspec-mock's
42
- approach of raising an error if a method is not declared as part of the
43
- double, since this raises errors earlier than later.
44
-
45
- ## Installation
46
-
47
- Add this line to your application's Gemfile:
48
-
49
- gem 'verified_double'
50
-
51
- And then execute:
52
-
53
- $ bundle
25
+ More information at https://www.relishapp.com/gsmendoza/verified-double.
54
26
 
55
- Or install it yourself as:
27
+ References
28
+ ----------
56
29
 
57
- $ gem install verified_double
30
+ 1. http://www.confreaks.com/videos/2452-railsconf2013-the-magic-tricks-of-testing
31
+ 2. https://www.relishapp.com/bogus/bogus/v/0-0-3/docs/contract-tests
32
+ 3. http://www.infoq.com/presentations/integration-tests-scam
58
33
 
59
- ## Contributing
34
+ Special thanks
35
+ --------------
60
36
 
61
- 1. Fork it
62
- 2. Create your feature branch (`git checkout -b my-new-feature`)
63
- 3. Commit your changes (`git commit -am 'Add some feature'`)
64
- 4. Push to the branch (`git push origin my-new-feature`)
65
- 5. Create new Pull Request
37
+ To @anathematic and [Inner Core Designs](http://icdesign.com.au) for sponsoring this gem :)
@@ -1,3 +1,11 @@
1
+ 0.1.0 - 2013-06-24
2
+ ------------------
3
+
4
+ * [#3] Pass Scenario: Verifying mocks for accessors.
5
+ * [#3] Pass Scenario: Verifying mocks for readers
6
+ * [#5] Remove rspec-fire dependency.
7
+ * [#5] Use VerifiedDouble to mock and stub doubles in own tests.
8
+
1
9
  0.0.2 - 2013-06-22
2
10
  ------------------
3
11
 
@@ -0,0 +1,107 @@
1
+ Feature: 05. Accessor method contracts
2
+ As a developer
3
+ I want it to easy to verify contracts for accessor methods
4
+
5
+ Background:
6
+ Given the following classes:
7
+ """
8
+ class ObjectUnderTest
9
+ def do_something(collaborator)
10
+ collaborator.value
11
+ end
12
+ end
13
+
14
+ class Collaborator
15
+ attr_accessor :value
16
+ end
17
+
18
+ class SomeValue
19
+ end
20
+ """
21
+
22
+ And the test suite includes VerifiedDouble to verify doubles with accessor methods:
23
+ """
24
+ require 'verified_double'
25
+ require 'main'
26
+
27
+ RSpec.configure do |config|
28
+ config.include VerifiedDouble::Matchers
29
+
30
+ config.after :suite do
31
+ VerifiedDouble.report_unverified_signatures(self)
32
+ end
33
+ end
34
+ """
35
+
36
+ Scenario: Verifying mocks for accessors
37
+ Given a test that uses VerifiedDouble to stub an object:
38
+ """
39
+ require 'spec_helper'
40
+ describe ObjectUnderTest do
41
+ let(:value) { SomeValue.new }
42
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator', value: value) }
43
+
44
+ it "tests something" do
45
+ ObjectUnderTest.new.do_something(instance_double)
46
+ end
47
+ end
48
+ """
49
+
50
+ And the test suite has a contract test for the stub:
51
+ """
52
+ require 'spec_helper'
53
+
54
+ describe Collaborator do
55
+ it { should verify_accessor_contract('Collaborator#value=>SomeValue') }
56
+ end
57
+ """
58
+
59
+ When I run the test suite
60
+ Then I should not see any output saying the stub is unverified
61
+
62
+ Scenario: Verifying mocks for readers
63
+ Given the following classes:
64
+ """
65
+ class ObjectUnderTest
66
+ def do_something(collaborator)
67
+ collaborator.value
68
+ end
69
+ end
70
+
71
+ class Collaborator
72
+ attr_reader :value
73
+
74
+ def initialize(value)
75
+ @value = value
76
+ end
77
+ end
78
+
79
+ class SomeValue
80
+ end
81
+ """
82
+
83
+ And a test that uses VerifiedDouble to stub an object:
84
+ """
85
+ require 'spec_helper'
86
+ describe ObjectUnderTest do
87
+ let(:value) { SomeValue.new }
88
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator', value: value) }
89
+
90
+ it "tests something" do
91
+ ObjectUnderTest.new.do_something(instance_double)
92
+ end
93
+ end
94
+ """
95
+
96
+ And the test suite has a contract test for the stub:
97
+ """
98
+ require 'spec_helper'
99
+
100
+ describe Collaborator do
101
+ subject { described_class.new(SomeValue.new) }
102
+ it { should verify_reader_contract('Collaborator#value=>SomeValue') }
103
+ end
104
+ """
105
+
106
+ When I run the test suite
107
+ Then I should not see any output saying the stub is unverified
@@ -1,4 +1,4 @@
1
- Feature: Customizing arguments and return values
1
+ Feature: 04. Customizing arguments and return values
2
2
  As a developer
3
3
  I want the ability to make contract arguments and return values more or less specific
4
4
 
@@ -24,7 +24,7 @@ Feature: Customizing arguments and return values
24
24
 
25
25
  RSpec.configure do |config|
26
26
  config.after :suite do
27
- VerifiedDouble::ReportUnverifiedSignatures.new(VerifiedDouble.registry, self).execute
27
+ VerifiedDouble.report_unverified_signatures(self)
28
28
  end
29
29
  end
30
30
  """
@@ -1,65 +1,37 @@
1
1
  # VerifiedDouble
2
2
 
3
- VerifiedDouble would record any mock made in the test suite. It
4
- would then verify if the mock is valid by checking if there is a test
5
- against it.
3
+ [![Build Status](https://travis-ci.org/gsmendoza/verified_double.png)](https://travis-ci.org/gsmendoza/verified_double)
6
4
 
7
- For example, let's say I mocked the save method of a model like so:
5
+ VerifiedDouble verifies mocks made in the test suite by checking if there are tests against them.
6
+
7
+ For example, let's say I mocked the created_at method of a model like this:
8
8
 
9
9
  item = VerifiedDouble.of_instance(Item)
10
- item.should_receive(:save).and_return(true)
10
+ item.should_receive(:created_at).and_return(Time.now)
11
11
 
12
- Calling `VerifiedDouble.of_instance` would record the :save interaction on
13
- item. When running the tests, the gem would look for a test that
14
- confirms if you can indeed call #save on Item. The test should also
15
- ensure that the method indeed returns a boolean value. Since this is hard
16
- to automate, the gem would just look for a test with the tag saying it
17
- verifies that contract:
12
+ The item double records its :created_at call. When
13
+ running the tests, the gem looks for a test that confirms if you can
14
+ indeed call #created_at on Item. The test should also ensure that the method
15
+ returns a Time object. Since this is hard to automate, the gem just looks
16
+ for a test with a tag saying it verifies that contract:
18
17
 
19
- it "tests something", verifies_contract: 'Item#save => Boolean' do
18
+ it "tests something", verifies_contract: 'Item#created_at()=>Time' do
20
19
  #...
21
20
  end
22
21
 
23
- If this test does not exist, the gem would complain that the mock is not
22
+ If this test does not exist, the gem will complain that the mock is not
24
23
  verified.
25
24
 
26
- This is an implementation of [contract tests](http://www.infoq.com/presentations/integration-tests-scam).
27
- Notes about the presentation [here](http://www.beletsky.net/2010/10/agileee-2010-j-b-rainsberger-integrated.html).
28
-
29
- There's already a gem that implements contract tests
30
- ([bogus](https://www.relishapp.com/bogus/bogus/v/0-0-3/docs/contract-tests)).
31
- However, I think there's room for an alternative because:
32
-
33
- 1. It's not clear from the Bogus [documentation](https://www.relishapp.com/bogus/bogus/v/0-0-3/docs/contract-tests/contract-tests-with-mocks)
34
- whether the gem verifies actual arguments/return values or just the types of those
35
- values. While the argument/return types are enough in most cases, sometimes
36
- the actual argument/return values are important. For example, if I mock
37
- Item.where(conditions), the actual conditions are important in
38
- verifying the validity of the where call.
39
-
40
- 2. [By design](https://www.relishapp.com/bogus/bogus/v/0-0-3/docs/fakes/faking-existing-classes#fakes-have-null-object-semantics),
41
- a Bogus fake would return itself to all its methods. I prefer rspec-mock's
42
- approach of raising an error if a method is not declared as part of the
43
- double, since this raises errors earlier than later.
44
-
45
- ## Installation
46
-
47
- Add this line to your application's Gemfile:
48
-
49
- gem 'verified_double'
50
-
51
- And then execute:
52
-
53
- $ bundle
25
+ More information at https://www.relishapp.com/gsmendoza/verified-double.
54
26
 
55
- Or install it yourself as:
27
+ References
28
+ ----------
56
29
 
57
- $ gem install verified_double
30
+ 1. http://www.confreaks.com/videos/2452-railsconf2013-the-magic-tricks-of-testing
31
+ 2. https://www.relishapp.com/bogus/bogus/v/0-0-3/docs/contract-tests
32
+ 3. http://www.infoq.com/presentations/integration-tests-scam
58
33
 
59
- ## Contributing
34
+ Special thanks
35
+ --------------
60
36
 
61
- 1. Fork it
62
- 2. Create your feature branch (`git checkout -b my-new-feature`)
63
- 3. Commit your changes (`git commit -am 'Add some feature'`)
64
- 4. Push to the branch (`git push origin my-new-feature`)
65
- 5. Create new Pull Request
37
+ To @anathematic and [Inner Core Designs](http://icdesign.com.au) for sponsoring this gem :)
@@ -0,0 +1,230 @@
1
+ Feature: 03. Rspec Mock compatibility
2
+ As a developer
3
+ I want VerifiedDouble to work with Rspec Mock API
4
+
5
+ Background:
6
+ Given the following classes:
7
+ """
8
+ class ObjectUnderTest
9
+ def do_something(collaborator, input)
10
+ collaborator.some_method(input)
11
+ end
12
+
13
+ def do_something_twice(collaborator, input)
14
+ collaborator.some_method(input)
15
+ collaborator.some_method(input)
16
+ end
17
+ end
18
+
19
+ class Collaborator
20
+ def some_method(input)
21
+ end
22
+ end
23
+
24
+ class SomeError < Exception
25
+ end
26
+
27
+ class SomeInput
28
+ end
29
+
30
+ class SomeOutput
31
+ end
32
+ """
33
+
34
+ And the test suite has a contract test for the mock:
35
+ """
36
+ require 'spec_helper'
37
+
38
+ describe 'Collaborator' do
39
+ it "tests something", verifies_contract: 'Collaborator#some_method(SomeInput)=>SomeOutput' do
40
+ # do nothing
41
+ end
42
+ end
43
+ """
44
+
45
+ And the test suite has an after(:suite) callback asking VerifiedDouble to report unverified doubles:
46
+ """
47
+ require 'verified_double'
48
+ require 'main'
49
+
50
+ RSpec.configure do |config|
51
+ config.after :suite do
52
+ VerifiedDouble.report_unverified_signatures(self)
53
+ end
54
+ end
55
+ """
56
+
57
+ Scenario: once
58
+ Given a test that uses VerifiedDouble to mock an object:
59
+ """
60
+ require 'spec_helper'
61
+ describe ObjectUnderTest do
62
+ let(:input) { SomeInput.new }
63
+ let(:output) { SomeOutput.new }
64
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator') }
65
+
66
+ it "tests something" do
67
+ instance_double.should_receive(:some_method).with(input).once.and_return(output)
68
+ ObjectUnderTest.new.do_something(instance_double, input)
69
+ end
70
+ end
71
+ """
72
+
73
+ When I run the test suite
74
+ Then I should not see any output saying the stub is unverified
75
+
76
+ Scenario: twice
77
+ Given a test that uses VerifiedDouble to mock an object:
78
+ """
79
+ require 'spec_helper'
80
+ describe ObjectUnderTest do
81
+ let(:input) { SomeInput.new }
82
+ let(:output) { SomeOutput.new }
83
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator') }
84
+
85
+ it "tests something" do
86
+ instance_double.should_receive(:some_method).with(input).twice.and_return(output)
87
+ ObjectUnderTest.new.do_something_twice(instance_double, input)
88
+ end
89
+ end
90
+ """
91
+
92
+ When I run the test suite
93
+ Then I should not see any output saying the stub is unverified
94
+
95
+ Scenario: exactly
96
+ Given a test that uses VerifiedDouble to mock an object:
97
+ """
98
+ require 'spec_helper'
99
+ describe ObjectUnderTest do
100
+ let(:input) { SomeInput.new }
101
+ let(:output) { SomeOutput.new }
102
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator') }
103
+
104
+ it "tests something" do
105
+ instance_double.should_receive(:some_method).with(input).exactly(1).and_return(output)
106
+ ObjectUnderTest.new.do_something(instance_double, input)
107
+ end
108
+ end
109
+ """
110
+
111
+ When I run the test suite
112
+ Then I should not see any output saying the stub is unverified
113
+
114
+ Scenario: at_least
115
+ Given a test that uses VerifiedDouble to mock an object:
116
+ """
117
+ require 'spec_helper'
118
+ describe ObjectUnderTest do
119
+ let(:input) { SomeInput.new }
120
+ let(:output) { SomeOutput.new }
121
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator') }
122
+
123
+ it "tests something" do
124
+ instance_double.should_receive(:some_method).with(input).at_least(:once).and_return(output)
125
+ ObjectUnderTest.new.do_something(instance_double, input)
126
+ end
127
+ end
128
+ """
129
+
130
+ When I run the test suite
131
+ Then I should not see any output saying the stub is unverified
132
+
133
+ Scenario: at_most
134
+ Given a test that uses VerifiedDouble to mock an object:
135
+ """
136
+ require 'spec_helper'
137
+ describe ObjectUnderTest do
138
+ let(:input) { SomeInput.new }
139
+ let(:output) { SomeOutput.new }
140
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator') }
141
+
142
+ it "tests something" do
143
+ instance_double.should_receive(:some_method).with(input).at_most(:once).and_return(output)
144
+ ObjectUnderTest.new.do_something(instance_double, input)
145
+ end
146
+ end
147
+ """
148
+
149
+ When I run the test suite
150
+ Then I should not see any output saying the stub is unverified
151
+
152
+ Scenario: any_number_of_times
153
+ Given a test that uses VerifiedDouble to mock an object:
154
+ """
155
+ require 'spec_helper'
156
+ describe ObjectUnderTest do
157
+ let(:input) { SomeInput.new }
158
+ let(:output) { SomeOutput.new }
159
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator') }
160
+
161
+ it "tests something" do
162
+ instance_double.should_receive(:some_method).with(input).any_number_of_times.and_return(output)
163
+ ObjectUnderTest.new.do_something(instance_double, input)
164
+ end
165
+ end
166
+ """
167
+
168
+ When I run the test suite
169
+ Then I should not see any output saying the stub is unverified
170
+
171
+ Scenario: and_raise
172
+ Given a test that uses VerifiedDouble to mock an object:
173
+ """
174
+ require 'spec_helper'
175
+ describe ObjectUnderTest do
176
+ let(:error) { SomeError.new }
177
+ let(:input) { SomeInput.new }
178
+ let(:output) { SomeOutput.new }
179
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator') }
180
+
181
+ it "tests something" do
182
+ instance_double.should_receive(:some_method).with(input).and_raise(error)
183
+ expect { ObjectUnderTest.new.do_something(instance_double, input) }.to raise_error(error)
184
+ end
185
+ end
186
+ """
187
+
188
+ And the test suite has a contract test for the mock:
189
+ """
190
+ require 'spec_helper'
191
+
192
+ describe 'Collaborator' do
193
+ it "tests something", verifies_contract: 'Collaborator#some_method(SomeInput)' do
194
+ # do nothing
195
+ end
196
+ end
197
+ """
198
+
199
+ When I run the test suite
200
+ Then I should not see any output saying the stub is unverified
201
+ Scenario: and_throw
202
+ Given a test that uses VerifiedDouble to mock an object:
203
+ """
204
+ require 'spec_helper'
205
+ describe ObjectUnderTest do
206
+ let(:error_symbol) { :error_symbol }
207
+ let(:input) { SomeInput.new }
208
+ let(:output) { SomeOutput.new }
209
+ let(:instance_double) { VerifiedDouble.of_instance('Collaborator') }
210
+
211
+ it "tests something" do
212
+ instance_double.should_receive(:some_method).with(input).and_throw(error_symbol)
213
+ expect { ObjectUnderTest.new.do_something(instance_double, input) }.to throw_symbol(error_symbol)
214
+ end
215
+ end
216
+ """
217
+
218
+ And the test suite has a contract test for the mock:
219
+ """
220
+ require 'spec_helper'
221
+
222
+ describe 'Collaborator' do
223
+ it "tests something", verifies_contract: 'Collaborator#some_method(SomeInput)' do
224
+ # do nothing
225
+ end
226
+ end
227
+ """
228
+
229
+ When I run the test suite
230
+ Then I should not see any output saying the stub is unverified