developwithpassion_fakes 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ blah.rb
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.3@developwithpassion_fakes --create
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,5 @@
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
@@ -0,0 +1,229 @@
1
+ #developwithpassion_fakes
2
+
3
+ This is a really simple library to aid in AAA style testing. The primary driver for using this is to be able to make assertions on method calls to collaborators in actual assertions and not as part of setup. It is meant to be used to complement the current testing framework that you are using to aid in the creation of interaction based tests.
4
+
5
+ Here is a simple example
6
+
7
+ ```ruby
8
+ class SomeClass
9
+ def initialize(collaborator)
10
+ @collaborator = collaborator
11
+ end
12
+ def run()
13
+ @collaborator.send_message("Hi")
14
+ end
15
+ end
16
+
17
+ describe SomeClass do
18
+ context "when run" do
19
+ let(:collaborator){DevelopWithPassion::Fakes::Fake.new}
20
+ let(:sut){SomeClass.new(collaborator)}
21
+
22
+ before(:each) do
23
+ sut.run
24
+ end
25
+
26
+ it "should trigger its collaborator with the correct message" do
27
+ collaborator.received(:send_message).called_with("Hi").should_not be_nil
28
+ end
29
+ end
30
+ end
31
+ ```
32
+
33
+ ##Creating a new fake
34
+
35
+ To create a new fake, simply leverage the fake method that is mixed into the Kernel module.
36
+
37
+ ```ruby
38
+ require 'developwithpassion_fakes'
39
+
40
+ item = fake
41
+ ```
42
+
43
+ ##Specifying the behaviour of a fake
44
+
45
+ When scaffolding fake return values, the library behaves almost identically to the way RSpec stubs work.
46
+
47
+ ###Setup a method to return a value for a particular set of arguments
48
+ ```ruby
49
+ collaborator = fake
50
+
51
+ collaborator.stub(:name_of_method).with(arg1,arg2,arg3).and_return(return_value)
52
+ ```
53
+
54
+ ###Setup a method to return a value regardless of the arguments it is called with
55
+ ```ruby
56
+ collaborator = fake
57
+
58
+ #long handed way
59
+ collaborator.stub(:name_of_method).ignore_arg.and_return(return_value)
60
+
61
+ #preferred way
62
+ collaborator.stub(:name_of_method).and_return(return_value)
63
+ ```
64
+
65
+ ###Setup different return values for different argument sets
66
+ ```ruby
67
+ collaborator = fake
68
+
69
+ #Setup a return value for 1
70
+ collaborator.stub(:method).with(1).and_return(first_return_value)
71
+
72
+ #Setup a return value for 2
73
+ collaborator.stub(:method).with(2).and_return(second_return_value)
74
+
75
+ #Setup a return value when called with everything else
76
+ #if you are going to use this, make sure it is used after
77
+ #setting up return values for specific arguments
78
+ collaborator.stub(:method).and_return(value_to_return_with_arguments_other_than_1_and_2)
79
+ ```
80
+
81
+ ##Verifying calls made to the fake
82
+
83
+
84
+ ###Verifying when a call was made
85
+
86
+ The primary purpose of the library is to help you in doing interaction style testing in a AAA style. Assume the following class is one you would like to test:
87
+
88
+ ```ruby
89
+ class ItemToTest
90
+ def initialize(collaborator)
91
+ @collaborator = collaborator
92
+ end
93
+
94
+ def run
95
+ @collaborator.send_message("Hello World")
96
+ end
97
+ end
98
+ ```
99
+
100
+ ItemToTest is supposed to leverage its collaborator and calls its send_message method with the argument "Hello World". To verify this using AAA style, interaction testing you can do the following (I am using rspec, but you can use this with any testing library you wish):
101
+
102
+ ```ruby
103
+ describe ItemToTest do
104
+ context "when run" do
105
+ let(:collaborator){fake}
106
+ let(:sut){ItemToTest.new(collaborator)}
107
+
108
+ #I typically use a before block to specifically trigger the method that I am testing, so it cleanly
109
+ #separates it from the assertions I will make later
110
+ before(:each) do
111
+ sut.run
112
+ end
113
+
114
+ it "should trigger its collaborator with the correct message" do
115
+ collaborator.received(:send_message).called_with("Hello World").should_not be_nil
116
+ end
117
+ end
118
+ end
119
+ ```
120
+ From the example above, you can see that we created the fake and did not need to scaffold it with any behaviour.
121
+
122
+ ```ruby
123
+ let(:collaborator){fake}
124
+ ```
125
+
126
+ You can also see that we are create our System Under Test (sut) and provide it the collaborator:
127
+
128
+ ```ruby
129
+ let(:sut){ItemToTest.new(collaborator)}
130
+ ```
131
+
132
+ We then proceed to invoke the method on the component we are testing
133
+
134
+ ```ruby
135
+ before(:each) do
136
+ sut.run
137
+ end
138
+ ```
139
+
140
+ Last but not least, we verify that our collaborator was invoked and with the right arguments:
141
+
142
+ ```ruby
143
+ it "should trigger its collaborator with the correct message" do
144
+ collaborator.received(:send_message).called_with("Hello World").should_not be_nil
145
+ end
146
+ ```
147
+
148
+ The nice thing is we can make the assertions after the fact, as opposed to needing to do them as part of setup, which I find is a much more natural way to read things, when you need to do this style of test. Notice that the called_with method return a method_invocation that will be nil if the call was not received. My recommendation would be to create a test utility method that allows you to leverage your testing frameworks assertion library to make the above assertion more terse. The
149
+ following rspec sample demonstrates:
150
+
151
+ ```ruby
152
+ module RSpec
153
+ Matchers.define :have_received do|symbol,*args|
154
+ match do|fake|
155
+ fake.received(symbol).called_with(*args) != nil
156
+ end
157
+ end
158
+ end
159
+ ```
160
+
161
+ Using the above utility method turns the previous assertion:
162
+
163
+ ```ruby
164
+ collaborator.received(:send_message).called_with("Hello World").should_not be_nil
165
+ ```
166
+
167
+ To this:
168
+
169
+ ```ruby
170
+ collaborator.should have_received(:send_message,"Hello World")
171
+ ```
172
+
173
+ ###Verifying that a call should not have been made
174
+
175
+ Currently verifying that a call was not made does not take the arguments into consideration. It just ensures that no calls to a particular named method were made. Here is an example:
176
+
177
+ ```ruby
178
+ class FirstCollaborator
179
+ def send_message(message)
180
+ end
181
+ end
182
+ class SecondCollaborator
183
+ def send_message(message)
184
+ end
185
+ end
186
+
187
+ class SomeItem
188
+ def initialize
189
+ @first = FirstCollaborator.new
190
+ @second = SecondCollaborator.new
191
+ end
192
+
193
+ def first_behaviour
194
+ @first.send_message("Hello")
195
+ end
196
+
197
+ def second_behaviour
198
+ @second.send_message("World")
199
+ end
200
+ end
201
+
202
+ describe SomeItem do
203
+ context "when run" do
204
+ let(:first){fake}
205
+ let(:second){fake}
206
+
207
+ before(:each) do
208
+ FirstCollaborator.stub(:new).and_return(first)
209
+ SecondCollaborator.stub(:new).and_return(second)
210
+ @sut = SomeItem.new
211
+ end
212
+
213
+ before(:each) do
214
+ @sut.first_behaviour
215
+ end
216
+
217
+ it "should trigger its collaborator with the correct message" do
218
+ first.should have_received(:send_message,"Hello")
219
+ end
220
+
221
+ it "should not trigger its second collaborator" do
222
+ #again, here would be another option to use a convienience test utility method
223
+ second.never_received?(:send_message).should be_true
224
+ end
225
+ end
226
+ end
227
+ ```
228
+
229
+ As you can see, in this test we want to verify that one collaborator was triggered and the other not.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -13,15 +13,15 @@ Gem::Specification.new do |s|
13
13
  s.description = %q{Faking library that allows inspection of received calls after they have been made. Also supports tracking calls with multiple argument sets.}
14
14
  s.rubyforge_project = "developwithpassion_fakes"
15
15
 
16
- s.files = `git ls-files | grep -P "^(dev|lib)"`.split("\n")
16
+ s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  # specify any dependencies here; for example:
22
- s.add_development_dependency "rspec-core"
23
- s.add_development_dependency "rspec-expectations"
22
+ s.add_development_dependency "rspec"
24
23
  s.add_development_dependency "rake"
25
24
  s.add_development_dependency "guard"
26
- # s.add_runtime_dependency "rest-client"
25
+ s.add_development_dependency "guard-rspec"
26
+ s.add_runtime_dependency "developwithpassion_arrays"
27
27
  end
@@ -1,3 +1,4 @@
1
+ require 'developwithpassion_arrays'
1
2
  require 'developwithpassion_fakes/arg_behaviour'
2
3
  require 'developwithpassion_fakes/arg_set'
3
4
  require 'developwithpassion_fakes/fake'
@@ -2,21 +2,21 @@ module DevelopWithPassion
2
2
  module Fakes
3
3
  class IgnoreSet
4
4
  include ArgBehaviour
5
- attr_reader :arg_sets
6
5
 
7
6
  def initialize
7
+ array :arg_sets do|a|
8
+ a.mutator :capture_args do|args|
9
+ @times_called += 1
10
+ @arg_sets << args
11
+ end
12
+ end
8
13
  @times_called = 0
9
- @arg_sets = []
10
14
  end
11
15
 
12
16
  def matches?(args)
13
17
  return true
14
18
  end
15
19
 
16
- def capture_args(args)
17
- @times_called += 1
18
- @arg_sets << args
19
- end
20
20
 
21
21
  def was_called_with?(args)
22
22
  return @arg_sets.select{|set| set == args}.count > 0
@@ -2,6 +2,12 @@ module DevelopWithPassion
2
2
  module Fakes
3
3
  class MethodStub
4
4
  def initialize(arg_sets = [])
5
+ array :arg_sets do|a|
6
+ a.mutator :add_new_set do|set|
7
+ @arg_sets << set
8
+ set
9
+ end
10
+ end
5
11
  @arg_sets = arg_sets
6
12
  end
7
13
 
@@ -9,10 +15,6 @@ module DevelopWithPassion
9
15
  return add_new_set(ArgSet.new(args))
10
16
  end
11
17
 
12
- def add_new_set(set)
13
- @arg_sets << set
14
- return set
15
- end
16
18
 
17
19
  def ignore_arg
18
20
  return add_new_set(IgnoreSet.new)
@@ -1,5 +1,5 @@
1
1
  module DevelopWithPassion
2
2
  module Fakes
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: developwithpassion_fakes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,8 +12,8 @@ cert_chain: []
12
12
  date: 2012-03-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rspec-core
16
- requirement: &70100720547900 !ruby/object:Gem::Requirement
15
+ name: rspec
16
+ requirement: &70202805267560 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70100720547900
24
+ version_requirements: *70202805267560
25
25
  - !ruby/object:Gem::Dependency
26
- name: rspec-expectations
27
- requirement: &70100720547360 !ruby/object:Gem::Requirement
26
+ name: rake
27
+ requirement: &70202805267080 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70100720547360
35
+ version_requirements: *70202805267080
36
36
  - !ruby/object:Gem::Dependency
37
- name: rake
38
- requirement: &70100720546900 !ruby/object:Gem::Requirement
37
+ name: guard
38
+ requirement: &70202805266440 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70100720546900
46
+ version_requirements: *70202805266440
47
47
  - !ruby/object:Gem::Dependency
48
- name: guard
49
- requirement: &70100720546440 !ruby/object:Gem::Requirement
48
+ name: guard-rspec
49
+ requirement: &70202805265900 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,18 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70100720546440
57
+ version_requirements: *70202805265900
58
+ - !ruby/object:Gem::Dependency
59
+ name: developwithpassion_arrays
60
+ requirement: &70202805265420 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70202805265420
58
69
  description: Faking library that allows inspection of received calls after they have
59
70
  been made. Also supports tracking calls with multiple argument sets.
60
71
  email:
@@ -63,6 +74,12 @@ executables: []
63
74
  extensions: []
64
75
  extra_rdoc_files: []
65
76
  files:
77
+ - .gitignore
78
+ - .rvmrc
79
+ - Gemfile
80
+ - Guardfile
81
+ - README.md
82
+ - Rakefile
66
83
  - developwithpassion_fakes.gemspec
67
84
  - lib/developwithpassion_fakes.rb
68
85
  - lib/developwithpassion_fakes/arg_behaviour.rb
@@ -98,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
115
  version: '0'
99
116
  requirements: []
100
117
  rubyforge_project: developwithpassion_fakes
101
- rubygems_version: 1.8.15
118
+ rubygems_version: 1.8.17
102
119
  signing_key:
103
120
  specification_version: 3
104
121
  summary: Simple faking library