flexmock 0.6.1 → 0.6.2

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/CHANGELOG CHANGED
@@ -1,7 +1,13 @@
1
- 2006-10-17 Jim Weirich <jim@weirichhouse.org>
2
-
3
1
  = Changes for FlexMock
4
2
 
3
+ == Version 0.6.2
4
+
5
+ * flexmock() with a block now always returns the domain object.
6
+ flexmock() without a block returns the mock object. Note that for
7
+ normal mocks, the domain and mock objects are the same. For partial
8
+ mocks, the mock is separate from the domain object.
9
+ * Added +and_raise+ to the list of expection specifications.
10
+
5
11
  == Version 0.6.1
6
12
 
7
13
  * Fixed bug that prevented mocks from mocking field assignment operators.
data/README CHANGED
@@ -3,7 +3,7 @@
3
3
  FlexMock is a simple, but flexible, mock object library for Ruby unit
4
4
  testing.
5
5
 
6
- Version :: 0.6.1
6
+ Version :: 0.6.2
7
7
 
8
8
  = Links
9
9
 
@@ -236,6 +236,14 @@ object. See theFlexMock::Expectation for more details.
236
236
 
237
237
  Alias for <tt>and_return</tt>.
238
238
 
239
+ * <b>and_raise(exception, *args)</b>
240
+
241
+ Declares that the expected messsage will raise the specified
242
+ exception. If +exception+ is an exception class, then the raised
243
+ exception will be constructed from the class with +new+ given the
244
+ supplied arguments. If +exception+ is an instance of an exception
245
+ class, then it will be raised directly.
246
+
239
247
  * <b>zero_or_more_times</b>
240
248
 
241
249
  Declares that the expected message is may be sent zero or more times
data/Rakefile CHANGED
@@ -19,7 +19,7 @@ require 'rake/contrib/rubyforgepublisher'
19
19
  CLEAN.include('*.tmp')
20
20
  CLOBBER.include("html", 'pkg')
21
21
 
22
- PKG_VERSION = '0.6.1'
22
+ PKG_VERSION = '0.6.2'
23
23
 
24
24
  PKG_FILES = FileList[
25
25
  '[A-Z]*',
@@ -66,13 +66,16 @@ end
66
66
 
67
67
  # RCov Target --------------------------------------------------------
68
68
 
69
- require 'rcov/rcovtask'
70
-
71
- Rcov::RcovTask.new do |t|
72
- t.libs << "test"
73
- t.rcov_opts = ['-xRakefile', '-xrakefile', '-xpublish.rf', '--text-report']
74
- t.test_files = FileList['test/test*.rb']
75
- t.verbose = true
69
+ begin
70
+ require 'rcov/rcovtask'
71
+
72
+ Rcov::RcovTask.new do |t|
73
+ t.libs << "test"
74
+ t.rcov_opts = ['-xRakefile', '-xrakefile', '-xpublish.rf', '--text-report']
75
+ t.test_files = FileList['test/test*.rb']
76
+ t.verbose = true
77
+ end
78
+ rescue LoadError => ex
76
79
  end
77
80
 
78
81
  # RDoc Target --------------------------------------------------------
@@ -0,0 +1,101 @@
1
+ = FlexMock 0.6.2 Released
2
+
3
+ FlexMock is a flexible mocking library for use in unit testing and behavior
4
+ specification in Ruby. Version 0.6.2 introduces a two minor enhancements.
5
+
6
+ == New in 0.6.2
7
+
8
+ * When creating a partial mock using a block, flexmock() now returns
9
+ the domain object rather than the mock proxy. This allows the
10
+ following to work:
11
+
12
+ obj = flexmock(Something.new) { |m| m.should_receive(:hi).once }
13
+ obj.hi
14
+
15
+ See http://onestepback.org/index.cgi/Tech/Ruby/FlexMockReturns.red
16
+ for more details.
17
+
18
+ * The +and_raise+ method is now supported for directly specifying that
19
+ exceptions will be thrown from a mock.
20
+
21
+ == What is FlexMock?
22
+
23
+ FlexMock is a flexible framework for creating mock object for testing. When
24
+ running unit tests, it is often desirable to use isolate the objects being
25
+ tested from the "real world" by having them interact with simplified test
26
+ objects. Sometimes these test objects simply return values when called, other
27
+ times they verify that certain methods were called with particular arguments
28
+ in a particular order.
29
+
30
+ FlexMock makes creating these test objects easy.
31
+
32
+ === Features
33
+
34
+ * Easy integration with both Test::Unit and RSpec. Mocks created with the
35
+ flexmock method are automatically verified at the end of the test or
36
+ example.
37
+
38
+ * A fluent interface that allows mock behavior to be specified very
39
+ easily.
40
+
41
+ * A "record mode" where an existing implementation can record its
42
+ interaction with a mock for later validation against a new
43
+ implementation.
44
+
45
+ * Easy mocking of individual methods in existing, non-mock objects.
46
+
47
+ * The ability to cause classes to instantiate test instances (instead of real
48
+ instances) for the duration of a test.
49
+
50
+ === Example
51
+
52
+ Suppose you had a Dog object that wagged a tail when it was happy.
53
+ Something like this:
54
+
55
+ class Dog
56
+ def initialize(a_tail)
57
+ @tail = a_tail
58
+ end
59
+ def happy
60
+ @tail.wag
61
+ end
62
+ end
63
+
64
+ To test the +Dog+ class without a real +Tail+ object (perhaps because
65
+ real +Tail+ objects activate servos in some robotic equipment), you
66
+ can do something like this:
67
+
68
+ require 'test/unit'
69
+ require 'flexmock/test_unit'
70
+
71
+ class TestDog < Test::Unit::TestCase
72
+ def test_dog_wags_tail_when_happy
73
+ tail = flexmock("tail")
74
+ tail.should_receive(:wag).once
75
+ dog = Dog.new(tail)
76
+ dog.happy
77
+ end
78
+ end
79
+
80
+ FlexMock will automatically verify that the mocked tail object received the
81
+ message +wag+ exactly one time. If it doesn't, the test will not pass.
82
+
83
+ See the FlexMock documentation at http://flexmock.rubyforge.org for details on
84
+ specifying arguments and return values on mocked methods, as well as a simple
85
+ technique for mocking tail objects when the Dog class creates the tail objects
86
+ directly.
87
+
88
+ == Availability
89
+
90
+ You can make sure you have the latest version with a quick RubyGems command:
91
+
92
+ gem install flexmock (you may need root/admin privileges)
93
+
94
+ Otherwise, you can get it from the more traditional places:
95
+
96
+ Download:: http://rubyforge.org/project/showfiles.php?group_id=170
97
+
98
+ You will find documentation at: http://flexmock.rubyforge.org.
99
+
100
+ -- Jim Weirich
101
+
@@ -139,7 +139,7 @@ class FlexMock
139
139
  # mock.should_receive(:f).with(String). # returns an
140
140
  # returns { |str| str.upcase } # upcased string
141
141
  #
142
- # +and_return+ is an alias for +returns+.
142
+ # +returns+ is an alias for +and_return+.
143
143
  #
144
144
  def and_return(*args, &block)
145
145
  @return_block =
@@ -152,6 +152,30 @@ class FlexMock
152
152
  end
153
153
  alias :returns :and_return # :nodoc:
154
154
 
155
+
156
+ # :call-seq:
157
+ # and_raise(an_exception)
158
+ # and_raise(SomeException)
159
+ # and_raise(SomeException, args, ...)
160
+ #
161
+ # Declares that the method will raise the given exception (with
162
+ # an optional message) when executed.
163
+ #
164
+ # * If an exception instance is given, then that instance will be
165
+ # raised.
166
+ #
167
+ # * If an exception class is given, the exception raised with be
168
+ # an instance of that class constructed with +new+. Any
169
+ # additional arguments in the argument list will be passed to
170
+ # the +new+ constructor when it is invoked.
171
+ #
172
+ # +raises+ is an alias for +and_return+.
173
+ #
174
+ def and_raise(exception, *args)
175
+ and_return { raise exception, *args }
176
+ end
177
+ alias :raises :and_raise
178
+
155
179
  # Declare that the method may be called any number of times.
156
180
  def zero_or_more_times
157
181
  at_least.never
@@ -13,14 +13,14 @@ require 'flexmock/noop'
13
13
 
14
14
  class FlexMock
15
15
 
16
- ####################################################################
16
+ # ######################################################################
17
17
  # Mock container methods
18
18
  #
19
- # Include this module in to get integration with FlexMock. When
20
- # this module is included, mocks may be created with a simple call
21
- # to the +flexmock+ method. Mocks created with via the method call
22
- # will automatically be verified in the teardown of the test case.
23
- #
19
+ # Include this module in to get integration with FlexMock. When this module
20
+ # is included, mocks may be created with a simple call to the +flexmock+
21
+ # method. Mocks created with via the method call will automatically be
22
+ # verified in the teardown of the test case.
23
+ #
24
24
  module MockContainer
25
25
  # Do the flexmock specific teardown stuff. If you need finer control,
26
26
  # you can use either +flexmock_verify+ or +flexmock_close+.
@@ -48,11 +48,10 @@ class FlexMock
48
48
  @flexmock_created_mocks = []
49
49
  end
50
50
 
51
- # Create a mocking object in the FlexMock framework. The +flexmock+
52
- # method has a number of options available, depending on just what
53
- # kind of mocking object your require. Mocks created via +flexmock+
54
- # will be automatically verify during the teardown phase of your
55
- # test framework.
51
+ # Create a mocking object in the FlexMock framework. The +flexmock+
52
+ # method has a number of options available, depending on just what kind of
53
+ # mocking object your require. Mocks created via +flexmock+ will be
54
+ # automatically verify during the teardown phase of your test framework.
56
55
  #
57
56
  # :call-seq:
58
57
  # flexmock() { |mock| ... }
@@ -64,6 +63,16 @@ class FlexMock
64
63
  # flexmock(real_object, name, expect_hash) { |mock| ... }
65
64
  # flexmock(:base, string, name, expect_hash) { |mock| ... }
66
65
  #
66
+ # <b>Note:</b> A plain flexmock() call without a block will return the
67
+ # mock object (the object that interprets <tt>should_receive</tt> and its
68
+ # brethern). A flexmock() call that _includes_ a block will return the
69
+ # domain objects (the object that will interpret domain messages) since
70
+ # the mock will be passed to the block for configuration. With regular
71
+ # mocks, this distinction is unimportant because the mock object and the
72
+ # domain object are the same object. However, with partial mocks, the
73
+ # mock object is separation from the domain object. Keep that distinciton
74
+ # in mind.
75
+ #
67
76
  # name ::
68
77
  # Name of the mock object. If no name is given, "unknown" is used for
69
78
  # full mocks and "flexmock(<em>real_object</em>)" is used for partial
@@ -93,37 +102,40 @@ class FlexMock
93
102
  # partial mock object. This explicit tag is only needed if you
94
103
  # want to use a string or a symbol as the mock base (string and
95
104
  # symbols would normally be interpretted as the mock name).
96
- #
105
+ #
97
106
  # &block ::
98
107
  # If a block is given, then the mock object is passed to the block and
99
- # expectations may be configured within the block.
108
+ # expectations may be configured within the block. When a block is given
109
+ # for a partial mock, flexmock will return the domain object rather than
110
+ # the mock object.
100
111
  #
101
112
  def flexmock(*args)
102
113
  name = nil
103
114
  quick_defs = {}
104
- stub_target = nil
115
+ domain_obj = nil
105
116
  while ! args.empty?
106
117
  case args.first
107
118
  when :base
108
119
  args.shift
109
- stub_target = args.shift
120
+ domain_obj = args.shift
110
121
  when String, Symbol
111
122
  name = args.shift.to_s
112
123
  when Hash
113
124
  quick_defs = args.shift
114
125
  else
115
- stub_target = args.shift
126
+ domain_obj = args.shift
116
127
  end
117
128
  end
118
- if stub_target
119
- mock = flexmock_make_stub(stub_target, name)
129
+ if domain_obj
130
+ mock = flexmock_make_partial_proxy(domain_obj, name)
120
131
  else
121
132
  mock = FlexMock.new(name || "unknown")
133
+ domain_obj = mock
122
134
  end
123
135
  flexmock_quick_define(mock, quick_defs)
124
136
  yield(mock) if block_given?
125
137
  flexmock_remember(mock)
126
- mock
138
+ block_given? ? domain_obj : mock
127
139
  end
128
140
  alias flexstub flexmock
129
141
 
@@ -131,7 +143,7 @@ class FlexMock
131
143
 
132
144
  # Create a PartialMock for the given object. Use +name+ as the name
133
145
  # of the mock object.
134
- def flexmock_make_stub(obj, name)
146
+ def flexmock_make_partial_proxy(obj, name)
135
147
  name ||= "flexmock(#{obj.class.to_s})"
136
148
  obj.instance_eval {
137
149
  @flexmock_proxy ||= PartialMock.new(obj, FlexMock.new(name))
@@ -33,8 +33,15 @@ module ExtendedShouldReceiveTests
33
33
  assert_equal :baz, @obj.bar(1)
34
34
  end
35
35
 
36
+ def test_count_contraints_apply_to_all_expectations
37
+ @mock.should_receive(:foo, :bar => :baz).once
38
+ @obj.foo
39
+ assert_raise(Test::Unit::AssertionFailedError) { @mock.mock_verify }
40
+ end
41
+
36
42
  def test_multiple_should_receives_are_allowed
37
- @mock.should_receive(:hi).and_return(:bye).should_receive(:hello => :goodbye)
43
+ @mock.should_receive(:hi).and_return(:bye).
44
+ should_receive(:hello => :goodbye)
38
45
  assert_equal :bye, @obj.hi
39
46
  assert_equal :goodbye, @obj.hello
40
47
  end
@@ -199,5 +199,20 @@ class TestStubbing < Test::Unit::TestCase
199
199
  partial_mock = flexmock(obj)
200
200
  assert_equal "flexmock(Object)", partial_mock.mock.mock_name
201
201
  end
202
+
203
+ def test_partials_can_be_defined_in_a_block
204
+ dog = Dog.new
205
+ flexmock(dog) do |m|
206
+ m.should_receive(:bark).and_return(:growl)
207
+ end
208
+ assert_equal :growl, dog.bark
209
+ end
210
+
211
+ def test_partials_defining_block_return_real_obj_not_proxy
212
+ dog = flexmock(Dog.new) do |m|
213
+ m.should_receive(:bark).and_return(:growl)
214
+ end
215
+ assert_equal :growl, dog.bark
216
+ end
202
217
 
203
218
  end
@@ -76,6 +76,48 @@ class TestFlexMockShoulds < Test::Unit::TestCase
76
76
  end
77
77
  end
78
78
 
79
+ class MyError < RuntimeError
80
+ end
81
+
82
+ def test_and_raises_with_exception_class_throws_exception
83
+ FlexMock.use do |m|
84
+ m.should_receive(:failure).and_raise(MyError)
85
+ assert_raise MyError do
86
+ m.failure
87
+ end
88
+ end
89
+ end
90
+
91
+ def test_and_raises_with_arguments_throws_exception_made_with_args
92
+ FlexMock.use do |m|
93
+ m.should_receive(:failure).and_raise(MyError, "my message")
94
+ ex = assert_raise MyError do
95
+ m.failure
96
+ end
97
+ assert_equal "my message", ex.message
98
+ end
99
+ end
100
+
101
+ def test_and_raises_with_a_specific_exception_throws_the_exception
102
+ FlexMock.use do |m|
103
+ err = MyError.new
104
+ m.should_receive(:failure).and_raise(err)
105
+ ex = assert_raise MyError do
106
+ m.failure
107
+ end
108
+ assert_equal err, ex
109
+ end
110
+ end
111
+
112
+ def test_raises_is_an_alias_for_and_raise
113
+ FlexMock.use do |m|
114
+ m.should_receive(:failure).raises(RuntimeError)
115
+ ex = assert_raise RuntimeError do
116
+ m.failure
117
+ end
118
+ end
119
+ end
120
+
79
121
  def test_multiple_expectations
80
122
  FlexMock.use do |m|
81
123
  m.should_receive(:hi).with(1).returns(10)
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
2
+ rubygems_version: 0.9.4.1
3
3
  specification_version: 1
4
4
  name: flexmock
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.6.1
7
- date: 2007-05-08 00:00:00 -04:00
6
+ version: 0.6.2
7
+ date: 2007-06-27 00:00:00 -04:00
8
8
  summary: Simple and Flexible Mock Objects for Testing
9
9
  require_paths:
10
10
  - lib
@@ -75,6 +75,7 @@ files:
75
75
  - doc/releases/flexmock-0.5.1.rdoc
76
76
  - doc/releases/flexmock-0.6.0.rdoc
77
77
  - doc/releases/flexmock-0.6.1.rdoc
78
+ - doc/releases/flexmock-0.6.2.rdoc
78
79
  test_files: []
79
80
 
80
81
  rdoc_options:
@@ -95,6 +96,7 @@ extra_rdoc_files:
95
96
  - doc/releases/flexmock-0.5.1.rdoc
96
97
  - doc/releases/flexmock-0.6.0.rdoc
97
98
  - doc/releases/flexmock-0.6.1.rdoc
99
+ - doc/releases/flexmock-0.6.2.rdoc
98
100
  executables: []
99
101
 
100
102
  extensions: []