flexmock 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,26 @@
1
1
  = Changes for FlexMock
2
2
 
3
+ == Version 0.6.3
4
+
5
+ * Added flexmodel() for better support of mocking ActiveRecord models.
6
+
7
+ * Fixed comment for singleton?
8
+
9
+ * Fixed coverage report for the partial mocking class.
10
+
11
+ * Fixed bug when partial mock objects reported they respond to a
12
+ method but they actually didn't.
13
+
14
+ * The flexmock() method now _always_ returns a combination domain/mock
15
+ object. For partial mocks, this implies that the domain object now
16
+ has mock support methods on it (e.g. should_receive).
17
+
18
+ * Safe mode for partials was introduced for the small number of cases
19
+ where mock support methods in the domain object would cause
20
+ problems.
21
+
22
+ * Internally renamed PartialMock to PartialMockProxy.
23
+
3
24
  == Version 0.6.2
4
25
 
5
26
  * flexmock() with a block now always returns the domain object.
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.2
6
+ Version :: 0.6.2.1
7
7
 
8
8
  = Links
9
9
 
@@ -53,7 +53,8 @@ Here's the complete example:
53
53
  end
54
54
  end
55
55
 
56
- You can find an extended example of FlexMock in {Google Example}[http://flexmock.rubyforge.org/files/doc/GoogleExample_rdoc.html].
56
+ You can find an extended example of FlexMock in {Google
57
+ Example}[http://flexmock.rubyforge.org/files/doc/GoogleExample_rdoc.html].
57
58
 
58
59
  == Test::Unit Integration
59
60
 
@@ -94,53 +95,100 @@ FlexMock also supports integration with the RSpec behavior specification framewo
94
95
  end
95
96
  end
96
97
 
97
- If you wish to try this prior to the release of RSpec 0.9.0, check out the trunk of the RSpec subversion repository.
98
+ If you wish to try this prior to the release of RSpec 0.9.0, check out
99
+ the trunk of the RSpec subversion repository.
98
100
 
99
101
  == Quick Reference
100
102
 
101
103
  === Creating Mock Objects
102
104
 
103
- The +flexmock+ method is used to create mocks in various configurations. Here's a quick rundown of the most common options. See FlexMock::MockContainer#flexmock for more details.
105
+ The +flexmock+ method is used to create mocks in various
106
+ configurations. Here's a quick rundown of the most common options.
107
+ See FlexMock::MockContainer#flexmock for more details.
104
108
 
105
- * <b>m = flexmock("joe")</b>
109
+ * <b>mock = flexmock("joe")</b>
106
110
 
107
111
  Create a mock object named "joe" (the name is used in reporting errors).
108
112
 
109
- * <b>m = flexmock(:foo => :bar, :baz => :froz)</b>
113
+ * <b>mock = flexmock(:foo => :bar, :baz => :froz)</b>
110
114
 
111
115
  Create a mock object and define two mocked methods (:foo and :baz) that
112
116
  return the values :bar and :froz respectively. This is useful when creating
113
117
  mock objects with just a few methods and simple return values.
114
118
 
115
- * <b>m = flexmock("joe", :foo => :bar, :bar => :froz)</b>
119
+ * <b>mock = flexmock("joe", :foo => :bar, :bar => :froz)</b>
116
120
 
117
121
  You can combine the mock name and an expectation hash in the same call to
118
122
  flexmock.
119
123
 
120
- * <b>m = flexmock(real_object)</b>
124
+ * <b>partial_mock = flexmock(real_object)</b>
121
125
 
122
126
  If you you give +flexmock+ a real object in the argument list, it will treat
123
127
  that real object as a base for a partial mock object. The return value +m+
124
128
  may be used to set expectations. The real_object should be used in the
125
129
  reference portion of the test.
126
130
 
127
- * <b>m = flexmock(real_object, "name", :foo => :baz)</b>
131
+ * <b>partial_mock = flexmock(real_object, "name", :foo => :baz)</b>
128
132
 
129
133
  Names and expectation hashes may be used with partial mocks as well.
130
134
 
131
- * <b>m = flexmock(:base, real_string_object)</b>
135
+ * <b>partial_mock = flexmock(:base, real_string_object)</b>
132
136
 
133
137
  Since Strings (and Symbols for that matter) are used for mock names,
134
138
  FlexMock will not recognize them as the base for a partial mock. To force a
135
139
  string to be used as a partial mock base, proceed the string object in the
136
140
  calling sequence with :base.
137
141
 
138
- * <b>m = flexmock(...) { |mock| mock.should_receive(...) }</b>
142
+ * <b>partial_mock = flexmock(:safe, real_object) { |mock| mock.should_receive(...) }</b>
143
+
144
+ When mocking real objects (i.e. "partial mocks"), FlexMock will add
145
+ a handful of mock related methods to the actual object (see below
146
+ for list of method names). If one or more of these added methods
147
+ collide with an existing method on the partial mock, then there are problems.
148
+
149
+ FlexMock offers a "safe" mode for partial mocks that does not add
150
+ these methods. Indicate safe mode by passing the symbol :safe as
151
+ the first argument of flexmock. A block <em>is required</em> when
152
+ using safe mode (the partial_mock returned in safe mode does not
153
+ have a +should_receive+ method).
154
+
155
+ The methods added to partial mocks in non-safe mode are:
156
+
157
+ * should_receive
158
+ * new_instances
159
+ * any_instance (note: deprecated)
160
+ * mock
161
+ * mock_teardown
162
+ * mock_setup
163
+
164
+ * <b>mock = flexmock(...) { |mock| mock.should_receive(...) }</b>
139
165
 
140
166
  If a block is given to any of the +flexmock+ forms, the mock object will be
141
167
  passed to the block as an argument. Code in the block can set the desired
142
168
  expectations for the mock object.
143
169
 
170
+ * <b>mock_model = flexmodel(YourModel, ...) { |mock| mock.should_receive(...) }</b>
171
+
172
+ The flexmodel() method will return a pure mock (not a partial mock)
173
+ that will have some ActiveRecord specific methods defined.
174
+ YourModel should be the class of an ActiveRecord model. These
175
+ predefined methods make it a bit easier to mock out ActiveRecord
176
+ model objects in a Rails application. Other that the predefined
177
+ mocked methods, the mock returned is a standard FlexMock mock
178
+ object.
179
+
180
+ The predefined mocked methods are:
181
+
182
+ * id -- returns a unique ID for each mocked model.
183
+ * to_params -- returns a stringified version of the id.
184
+ * new_record? -- returns false.
185
+ * errors -- returns an empty (mocked) errors object.
186
+ * is_a?(other) -- returns true if other == YourModel.
187
+ * class -- returns YourModel.
188
+
189
+ The flexmodel() method is optional. You must require
190
+ 'flexmock/activerecord' to enable it.
191
+
144
192
  <b>NOTE:</b> Versions of FlexMock prior to 0.6.0 used +flexstub+ to create partial mocks. The +flexmock+ method now assumes all the functionality that was spread out between two different methods. +flexstub+ is still available for backward compatibility.
145
193
 
146
194
  === Expectation Declarators
data/Rakefile CHANGED
@@ -8,7 +8,7 @@
8
8
  # and distribution of modified versions of this work as long as the
9
9
  # above copyright notice is included.
10
10
  #+++
11
-
11
+ task :noop
12
12
  require 'rubygems'
13
13
  require 'rake/gempackagetask'
14
14
  require 'rake/clean'
@@ -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.2'
22
+ PKG_VERSION = '0.6.3'
23
23
 
24
24
  PKG_FILES = FileList[
25
25
  '[A-Z]*',
@@ -31,7 +31,7 @@ PKG_FILES = FileList[
31
31
 
32
32
  RDOC_FILES = FileList[
33
33
  'README',
34
- 'CHANGELOG',
34
+ 'CHANGES',
35
35
  'lib/**/*.rb',
36
36
  'doc/**/*.rdoc',
37
37
  ]
@@ -189,7 +189,7 @@ task :specs do
189
189
  end
190
190
 
191
191
  task :tag do
192
- sh %{svn copy #{SVNHOME}/trunk #{SVNHOME}/tags/rel-#{PKG_VERSION} -m 'Release #{PKG_VERSION}'}
192
+ sh "svn copy #{SVNHOME}/trunk #{SVNHOME}/tags/rel-#{PKG_VERSION} -m 'Release #{PKG_VERSION}'"
193
193
  end
194
194
 
195
195
  RUBY_FILES = FileList['**/*.rb']
@@ -197,3 +197,18 @@ RUBY_FILES.exclude(/^pkg/)
197
197
  task :dbg do
198
198
  RUBY_FILES.egrep(/DBG/)
199
199
  end
200
+
201
+ # Tagging ------------------------------------------------------------
202
+
203
+ module Tags
204
+ RUBY_FILES = FileList['**/*.rb'].exclude("pkg")
205
+ end
206
+
207
+ namespace "tags" do
208
+ task :emacs => Tags::RUBY_FILES do
209
+ puts "Making Emacs TAGS file"
210
+ sh "xctags -e #{Tags::RUBY_FILES}", :verbose => false
211
+ end
212
+ end
213
+
214
+ task :tags => ["tags:emacs"]
data/TAGS ADDED
@@ -0,0 +1,461 @@
1
+
2
+ install.rb,29
3
+ def indir(newdir)indir7,68
4
+
5
+ doc/jamis.rb,43
6
+ module RDocRDoc1,0
7
+ module PagePage2,12
8
+
9
+ lib/flexmock.rb,0
10
+
11
+ lib/flexmock/argument_matchers.rb,424
12
+ class FlexMockFlexMock14,338
13
+ class AnyMatcherAnyMatcher17,445
14
+ def ===(target)===18,464
15
+ def inspectinspect21,503
16
+ class EqualMatcherEqualMatcher28,655
17
+ def initialize(obj)initialize29,676
18
+ def ===(target)===32,725
19
+ def inspectinspect35,774
20
+ class ProcMatcherProcMatcher44,985
21
+ def initialize(&block)initialize45,1005
22
+ def ===(target)===48,1061
23
+ def inspectinspect51,1115
24
+
25
+ lib/flexmock/argument_types.rb,154
26
+ class FlexMockFlexMock14,350
27
+ module ArgumentTypesArgumentTypes21,643
28
+ def anyany23,726
29
+ def eq(obj)eq29,853
30
+ def on(&block)on36,1053
31
+
32
+ lib/flexmock/base.rb,0
33
+
34
+ lib/flexmock/composite.rb,30
35
+ class FlexMockFlexMock8,133
36
+
37
+ lib/flexmock/core.rb,736
38
+ class FlexMockFlexMock44,1236
39
+ def initialize(name="unknown")initialize50,1435
40
+ def mock_handle(sym, expected_count=nil, &block) # :nodoc:mock_handle66,1959
41
+ def mock_verifymock_verify72,2199
42
+ def mock_teardownmock_teardown83,2428
43
+ def mock_allocate_ordermock_allocate_order87,2504
44
+ def should_ignore_missingshould_ignore_missing92,2612
45
+ def method_missing(sym, *args, &block)method_missing98,2787
46
+ def respond_to?(sym)respond_to?113,3220
47
+ def method(sym)method118,3375
48
+ def should_receive(*args)should_receive147,4395
49
+ def should_expectshould_expect169,5078
50
+ def mock_wrap(&block)mock_wrap177,5268
51
+ def override_existing_method(sym)override_existing_method191,5819
52
+ def sclasssclass200,6039
53
+
54
+ lib/flexmock/core_class_methods.rb,239
55
+ class FlexMockFlexMock14,337
56
+ def should_receive(args) # :nodoc:should_receive26,798
57
+ def use(*names)use61,2024
58
+ def format_args(sym, args) # :nodoc:format_args77,2444
59
+ def check(msg, &block) # :nodoc:check87,2745
60
+
61
+ lib/flexmock/default_framework_adapter.rb,345
62
+ class FlexMockFlexMock14,337
63
+ class DefaultFrameworkAdapterDefaultFrameworkAdapter15,352
64
+ def assert_block(msg, &block)assert_block16,384
65
+ def assert_equal(a, b, msg=nil)assert_equal22,497
66
+ class AssertionFailedError < StandardError; endAssertionFailedError26,597
67
+ def assertion_failed_errorassertion_failed_error27,649
68
+
69
+ lib/flexmock/expectation.rb,1501
70
+ class FlexMockFlexMock14,337
71
+ class ExpectationExpectation28,872
72
+ def initialize(mock, sym)initialize34,1018
73
+ def to_sto_s46,1323
74
+ def verify_call(*args)verify_call52,1505
75
+ def eligible?eligible?60,1759
76
+ def validate_ordervalidate_order65,1880
77
+ def mock_verifymock_verify77,2317
78
+ def match_args(args)match_args85,2510
79
+ def match_arg(expected, actual)match_arg94,2856
80
+ def with(*args)with101,3085
81
+ def with_no_argswith_no_args107,3219
82
+ def with_any_argswith_any_args113,3352
83
+ def and_return(*args, &block)and_return144,4361
84
+ def and_raise(exception, *args)and_raise174,5267
85
+ def zero_or_more_timeszero_or_more_times180,5450
86
+ def times(limit)times187,5673
87
+ def nevernever196,6020
88
+ def onceonce203,6235
89
+ def twicetwice210,6450
90
+ def at_leastat_least222,6776
91
+ def at_mostat_most235,7155
92
+ def ordered(group_name=nil)ordered264,8424
93
+ class CompositeExpectationCompositeExpectation281,9010
94
+ def initializeinitialize284,9084
95
+ def add(expectation)add289,9180
96
+ def method_missing(sym, *args, &block)method_missing294,9321
97
+ def order_numberorder_number305,9700
98
+ def mockmock310,9810
99
+ def should_receive(*args, &block)should_receive316,9978
100
+ def to_sto_s321,10124
101
+ class ExpectationRecorderExpectationRecorder335,10582
102
+ def initializeinitialize338,10642
103
+ def method_missing(sym, *args, &block)method_missing343,10753
104
+ def apply(mock)apply351,11029
105
+
106
+ lib/flexmock/expectation_director.rb,236
107
+ class FlexMockFlexMock14,337
108
+ class ExpectationDirectorExpectationDirector20,549
109
+ def initialize(sym)initialize23,633
110
+ def call(*args)call37,1161
111
+ def <<(expectation)<<46,1504
112
+ def mock_verifymock_verify52,1663
113
+
114
+ lib/flexmock/mock_container.rb,488
115
+ class FlexMockFlexMock14,337
116
+ module MockContainerMockContainer24,743
117
+ def flexmock_teardownflexmock_teardown27,905
118
+ def flexmock_verifyflexmock_verify34,1063
119
+ def flexmock_closeflexmock_close43,1354
120
+ def flexmock(*args)flexmock112,4620
121
+ def flexmock_make_partial_proxy(obj, name)flexmock_make_partial_proxy146,5494
122
+ def flexmock_quick_define(mock, defs)flexmock_quick_define155,5799
123
+ def flexmock_remember(mocking_object)flexmock_remember163,6025
124
+
125
+ lib/flexmock/noop.rb,0
126
+
127
+ lib/flexmock/partial_mock.rb,1057
128
+ class FlexMockFlexMock14,337
129
+ class PartialMockPartialMock25,954
130
+ def initialize(obj, mock)initialize30,1105
131
+ def should_receive(*args)should_receive60,2218
132
+ def new_instances(*allocators, &block)new_instances88,3171
133
+ def any_instance(&block)any_instance106,3804
134
+ def invoke_original(method, args)invoke_original113,4036
135
+ def mock_verifymock_verify121,4330
136
+ def mock_teardownmock_teardown126,4458
137
+ def mock_allocate_ordermock_allocate_order138,4804
138
+ def sclasssclass145,4923
139
+ def singleton?(method_name)singleton?151,5064
140
+ def hide_existing_method(method_name)hide_existing_method161,5526
141
+ def create_alias_for_existing_method(method_name)create_alias_for_existing_method181,6240
142
+ def define_proxy_method(method_name)define_proxy_method199,6759
143
+ def restore_original_definition(method_name)restore_original_definition220,7459
144
+ def remove_current_method(method_name)remove_current_method232,7823
145
+ def detached?detached?237,7984
146
+ def new_name(old_name)new_name242,8092
147
+
148
+ lib/flexmock/recorder.rb,271
149
+ class FlexMockFlexMock14,347
150
+ class RecorderRecorder20,523
151
+ def initialize(mock)initialize24,629
152
+ def should_be_strict(is_strict=true)should_be_strict48,1561
153
+ def strict?strict?53,1675
154
+ def method_missing(sym, *args, &block)method_missing59,1805
155
+
156
+ lib/flexmock/rspec.rb,341
157
+ class FlexMockFlexMock14,337
158
+ class RSpecFrameworkAdapterRSpecFrameworkAdapter16,355
159
+ def assert_block(msg, &block)assert_block17,385
160
+ def assert_equal(a, b, msg=nil)assert_equal21,481
161
+ class AssertionFailedError < StandardError; endAssertionFailedError26,644
162
+ def assertion_failed_errorassertion_failed_error27,696
163
+
164
+ lib/flexmock/test_unit.rb,120
165
+ module TestTest14,354
166
+ module UnitUnit15,366
167
+ class TestCaseTestCase16,380
168
+ def teardownteardown25,695
169
+
170
+ lib/flexmock/test_unit_integration.rb,227
171
+ class FlexMockFlexMock15,357
172
+ module TestCaseTestCase29,917
173
+ def teardownteardown35,1092
174
+ class TestUnitFrameworkAdapterTestUnitFrameworkAdapter45,1301
175
+ def assertion_failed_errorassertion_failed_error47,1369
176
+
177
+ lib/flexmock/validators.rb,545
178
+ class FlexMockFlexMock14,337
179
+ class CountValidatorCountValidator19,473
180
+ def initialize(expectation, limit)initialize20,496
181
+ def eligible?(n)eligible?28,752
182
+ class ExactCountValidator < CountValidatorExactCountValidator36,917
183
+ def validate(n)validate39,1041
184
+ class AtLeastCountValidator < CountValidatorAtLeastCountValidator48,1332
185
+ def validate(n)validate51,1458
186
+ def eligible?(n)eligible?61,1875
187
+ class AtMostCountValidator < CountValidatorAtMostCountValidator69,2058
188
+ def validate(n)validate71,2173
189
+
190
+ test/test_container_methods.rb,1097
191
+ class TestFlexmockContainerMethods < Test::Unit::TestCaseTestFlexmockContainerMethods16,410
192
+ def test_simple_mock_creationtest_simple_mock_creation19,498
193
+ def test_mock_with_nametest_mock_with_name25,639
194
+ def test_mock_with_symbol_nametest_mock_with_symbol_name32,848
195
+ def test_mock_with_hashtest_mock_with_hash39,1063
196
+ def test_mock_with_name_and_hashtest_mock_with_name_and_hash45,1208
197
+ def test_mock_with_name_hash_and_blocktest_mock_with_name_hash_and_block54,1516
198
+ def test_basic_stubtest_basic_stub62,1739
199
+ def test_basic_stub_with_nametest_basic_stub_with_name69,1901
200
+ def test_stub_with_quick_definitionstest_stub_with_quick_definitions77,2161
201
+ def test_stub_with_name_quick_definitionstest_stub_with_name_quick_definitions83,2305
202
+ def test_stubs_are_auto_verifiedtest_stubs_are_auto_verified92,2629
203
+ def test_stubbing_a_stringtest_stubbing_a_string99,2831
204
+ def test_multiple_stubs_work_with_same_PartialMocktest_multiple_stubs_work_with_same_PartialMock105,2958
205
+ def test_multiple_stubs_layer_behaviortest_multiple_stubs_layer_behavior112,3123
206
+
207
+ test/test_default_framework_adapter.rb,475
208
+ class TestFlexmockDefaultFrameworkAdapter < Test::Unit::TestCaseTestFlexmockDefaultFrameworkAdapter15,352
209
+ def setupsetup16,417
210
+ def test_assert_block_raises_exception test_assert_block_raises_exception20,489
211
+ def test_assert_block_doesnt_raise_exceptiontest_assert_block_doesnt_raise_exception26,684
212
+ def test_assert_equal_doesnt_raise_exceptiontest_assert_equal_doesnt_raise_exception30,794
213
+ def test_assert_equal_can_failtest_assert_equal_can_fail34,900
214
+
215
+ test/test_example.rb,278
216
+ class TemperatureSamplerTemperatureSampler15,352
217
+ def initialize(sensor)initialize16,377
218
+ def average_tempaverage_temp20,430
219
+ class TestTemperatureSampler < Test::Unit::TestCaseTestTemperatureSampler27,562
220
+ def test_tempurature_samplertest_tempurature_sampler28,614
221
+
222
+ test/test_extended_should_receive.rb,797
223
+ module ExtendedShouldReceiveTestsExtendedShouldReceiveTests15,352
224
+ def test_accepts_expectation_hashtest_accepts_expectation_hash16,386
225
+ def test_accepts_list_of_methodstest_accepts_list_of_methods22,552
226
+ def test_contraints_apply_to_all_expectationstest_contraints_apply_to_all_expectations29,712
227
+ def test_count_contraints_apply_to_all_expectationstest_count_contraints_apply_to_all_expectations36,1001
228
+ def test_multiple_should_receives_are_allowedtest_multiple_should_receives_are_allowed42,1200
229
+ class TestExtendedShouldReceiveOnFullMocks < Test::Unit::TestCaseTestExtendedShouldReceiveOnFullMocks50,1417
230
+ def setupsetup54,1552
231
+ class TestExtendedShouldReceiveOnPartialMocks < Test::Unit::TestCaseTestExtendedShouldReceiveOnPartialMocks61,1622
232
+ def setupsetup65,1760
233
+
234
+ test/test_mock.rb,1777
235
+ class TestFlexMock < Test::Unit::TestCaseTestFlexMock15,352
236
+ def setupsetup16,394
237
+ def test_handletest_handle20,438
238
+ def test_handle_no_blocktest_handle_no_block27,576
239
+ def test_called_with_blocktest_called_with_block33,700
240
+ def test_return_valuetest_return_value40,892
241
+ def test_handle_missing_methodtest_handle_missing_method45,991
242
+ def test_ignore_missing_methodtest_ignore_missing_method53,1216
243
+ def test_good_countstest_good_counts59,1347
244
+ def test_bad_countstest_bad_counts67,1476
245
+ def test_undetermined_countstest_undetermined_counts78,1683
246
+ def test_zero_countstest_zero_counts87,1822
247
+ def test_file_io_with_usetest_file_io_with_use96,1995
248
+ def count_lines(stream)count_lines104,2193
249
+ def test_usetest_use112,2311
250
+ def test_failures_during_usetest_failures_during_use121,2462
251
+ def test_sequential_valuestest_sequential_values131,2675
252
+ def test_respond_to_returns_false_for_non_handled_methodstest_respond_to_returns_false_for_non_handled_methods140,2903
253
+ def test_respond_to_returns_true_for_explicit_methodstest_respond_to_returns_true_for_explicit_methods144,3038
254
+ def test_respond_to_returns_true_for_missing_methods_when_ignoring_missingtest_respond_to_returns_true_for_missing_methods_when_ignoring_missing149,3191
255
+ def test_respond_to_returns_true_for_missing_methods_when_ignoring_missing_using_shouldtest_respond_to_returns_true_for_missing_methods_when_ignoring_missing_using_should154,3372
256
+ def test_method_proc_raises_error_on_unknowntest_method_proc_raises_error_on_unknown159,3568
257
+ def test_method_returns_callable_proctest_method_returns_callable_proc165,3686
258
+ def test_method_returns_do_nothing_proc_for_missing_methodstest_method_returns_do_nothing_proc_for_missing_methods174,3936
259
+
260
+ test/test_naming.rb,404
261
+ class TestNaming < Test::Unit::TestCaseTestNaming15,352
262
+ def test_nametest_name16,392
263
+ def test_name_in_no_handler_found_errortest_name_in_no_handler_found_error21,475
264
+ def test_name_in_received_count_errortest_name_in_received_count_error30,705
265
+ def test_naming_with_usetest_naming_with_use39,935
266
+ def test_naming_with_multiple_mocks_in_usetest_naming_with_multiple_mocks_in_use45,1048
267
+
268
+ test/test_new_instances.rb,2475
269
+ class TestNewInstances < Test::Unit::TestCaseTestNewInstances15,352
270
+ class DogDog18,430
271
+ def barkbark19,442
272
+ def wagwag22,475
273
+ def self.makemake25,507
274
+ class CatCat30,550
275
+ def initialize(name, &block)initialize32,584
276
+ class ConnectionConnection38,692
277
+ def initialize(*args)initialize39,711
278
+ def send(args)send42,779
279
+ def post(args)post45,823
280
+ def test_new_instances_allows_stubbing_of_existing_methodstest_new_instances_allows_stubbing_of_existing_methods50,874
281
+ def test_any_instance_still_works_for_backwards_compatibilitytest_any_instance_still_works_for_backwards_compatibility58,1097
282
+ def test_new_instances_stubs_still_have_existing_methodstest_new_instances_stubs_still_have_existing_methods69,1413
283
+ def test_new_instances_will_pass_args_to_newtest_new_instances_will_pass_args_to_new77,1628
284
+ def test_new_gets_block_after_restubbingtest_new_gets_block_after_restubbing90,2034
285
+ def test_new_instances_stub_verification_happens_on_teardowntest_new_instances_stub_verification_happens_on_teardown103,2359
286
+ def test_new_instances_reports_error_on_non_classestest_new_instances_reports_error_on_non_classes113,2722
287
+ def test_can_stub_objects_created_with_allocate_instead_of_newtest_can_stub_objects_created_with_allocate_instead_of_new123,3004
288
+ def test_can_stub_objects_created_with_arbitrary_class_methodstest_can_stub_objects_created_with_arbitrary_class_methods131,3236
289
+ def test_stubbing_arbitrary_class_methods_leaves_new_alonetest_stubbing_arbitrary_class_methods_leaves_new_alone138,3461
290
+ def test_stubbing_new_and_allocate_doesnt_double_stub_objects_on_newtest_stubbing_new_and_allocate_doesnt_double_stub_objects_on_new145,3676
291
+ def test_stubbing_new_and_allocate_doesnt_double_stub_objects_on_allocatetest_stubbing_new_and_allocate_doesnt_double_stub_objects_on_allocate154,3878
292
+ def test_blocks_on_new_do_not_have_stubs_installedtest_blocks_on_new_do_not_have_stubs_installed167,4345
293
+ def test_new_instances_accept_chained_expectationstest_new_instances_accept_chained_expectations181,4685
294
+ def test_fancy_use_of_chained_should_receivedtest_fancy_use_of_chained_should_received189,4957
295
+ def test_writable_accessorstest_writable_accessors194,5114
296
+ def test_ordering_can_be_specifiedtest_ordering_can_be_specified200,5261
297
+ def test_ordering_can_be_specified_in_groupstest_ordering_can_be_specified_in_groups208,5457
298
+ def redirect_errorredirect_error218,5752
299
+
300
+ test/test_partial_mock.rb,3046
301
+ class TestStubbing < Test::Unit::TestCaseTestStubbing16,372
302
+ class DogDog19,446
303
+ def barkbark20,458
304
+ def Dog.createcreate23,491
305
+ def test_stub_command_add_behavior_to_arbitrary_objectstest_stub_command_add_behavior_to_arbitrary_objects28,540
306
+ def test_stub_command_can_configure_via_blocktest_stub_command_can_configure_via_block34,726
307
+ def test_stubbed_methods_can_take_blockstest_stubbed_methods_can_take_blocks42,925
308
+ def test_multiple_stubs_on_the_same_object_reuse_the_same_partial_mocktest_multiple_stubs_on_the_same_object_reuse_the_same_partial_mock49,1152
309
+ def test_multiple_methods_can_be_stubbedtest_multiple_methods_can_be_stubbed54,1301
310
+ def test_original_behavior_can_be_restoredtest_original_behavior_can_be_restored62,1555
311
+ def test_original_missing_behavior_can_be_restoredtest_original_missing_behavior_can_be_restored72,1888
312
+ def test_multiple_stubs_on_single_method_can_be_restored_missing_methodtest_multiple_stubs_on_single_method_can_be_restored_missing_method81,2163
313
+ def test_original_behavior_is_restored_when_multiple_methods_are_mockedtest_original_behavior_is_restored_when_multiple_methods_are_mocked92,2570
314
+ def test_original_behavior_is_restored_on_class_objectstest_original_behavior_is_restored_on_class_objects101,2895
315
+ def test_original_behavior_is_restored_on_singleton_methodstest_original_behavior_is_restored_on_singleton_methods108,3142
316
+ def obj.hi() :hello endhi110,3225
317
+ def test_original_behavior_is_restored_on_singleton_methods_with_multiple_stubstest_original_behavior_is_restored_on_singleton_methods_with_multiple_stubs118,3417
318
+ def obj.hi(n) "hello#{n}" endhi120,3520
319
+ def test_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubstest_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubs130,3837
320
+ def test_stubbing_file_shouldnt_break_writingtest_stubbing_file_shouldnt_break_writing146,4327
321
+ def test_original_behavior_is_restored_even_when_errorstest_original_behavior_is_restored_even_when_errors162,4762
322
+ def m.mock_verify() endmock_verify170,5073
323
+ def test_not_calling_stubbed_method_is_an_errortest_not_calling_stubbed_method_is_an_error173,5108
324
+ def test_mock_is_verified_when_the_stub_is_verifiedtest_mock_is_verified_when_the_stub_is_verified182,5333
325
+ def test_stub_can_have_explicit_nametest_stub_can_have_explicit_name191,5599
326
+ def test_unamed_stub_will_use_default_naming_conventiontest_unamed_stub_will_use_default_naming_convention197,5766
327
+ def test_partials_can_be_defined_in_a_blocktest_partials_can_be_defined_in_a_block203,5950
328
+ def test_partials_defining_block_return_real_obj_not_proxytest_partials_defining_block_return_real_obj_not_proxy211,6137
329
+ class LiarLiar218,6331
330
+ def respond_to?(method_name)respond_to?219,6344
331
+ def test_liar_actually_liestest_liar_actually_lies229,6513
332
+ def test_partial_mock_where_respond_to_is_true_yet_method_is_not_theretest_partial_mock_where_respond_to_is_true_yet_method_is_not_there234,6612
333
+
334
+ test/test_record_mode.rb,1428
335
+ module FailureAssertionFailureAssertion15,366
336
+ def assert_failsassert_fails17,402
337
+ class TestRecordMode < Test::Unit::TestCaseTestRecordMode24,513
338
+ def test_recording_mode_workstest_recording_mode_works28,623
339
+ def test_arguments_are_passed_to_recording_mode_blocktest_arguments_are_passed_to_recording_mode_block37,815
340
+ def test_recording_mode_handles_multiple_returnstest_recording_mode_handles_multiple_returns49,1109
341
+ def test_recording_mode_does_not_specify_ordertest_recording_mode_does_not_specify_order60,1376
342
+ def test_recording_mode_gets_block_args_tootest_recording_mode_gets_block_args_too71,1622
343
+ def test_recording_mode_should_validate_args_with_equalstest_recording_mode_should_validate_args_with_equals84,1934
344
+ def test_recording_mode_should_allow_arg_contraint_validationtest_recording_mode_should_allow_arg_contraint_validation95,2167
345
+ def test_recording_mode_should_handle_multiplicity_contraintstest_recording_mode_should_handle_multiplicity_contraints106,2405
346
+ def test_strict_record_mode_requires_exact_argument_matchestest_strict_record_mode_requires_exact_argument_matches118,2670
347
+ def test_strict_record_mode_requires_exact_orderingtest_strict_record_mode_requires_exact_ordering130,2948
348
+ def test_strict_record_mode_requires_oncetest_strict_record_mode_requires_once144,3251
349
+ def test_strict_record_mode_can_not_failtest_strict_record_mode_can_not_fail157,3524
350
+
351
+ test/test_samples.rb,142
352
+ class TestSamples < Test::Unit::TestCaseTestSamples17,378
353
+ def test_file_iotest_file_io25,748
354
+ def count_lines(file)count_lines33,999
355
+
356
+ test/test_should_receive.rb,6840
357
+ def mock_top_level_functionmock_top_level_function15,352
358
+ module KernelKernel20,394
359
+ def mock_kernel_functionmock_kernel_function21,408
360
+ class TestFlexMockShoulds < Test::Unit::TestCaseTestFlexMockShoulds26,455
361
+ def test_defaultstest_defaults35,871
362
+ def test_returns_with_valuetest_returns_with_value44,1039
363
+ def test_returns_with_multiple_valuestest_returns_with_multiple_values52,1208
364
+ def test_returns_with_blocktest_returns_with_block63,1468
365
+ def test_and_returns_aliastest_and_returns_alias72,1671
366
+ class MyError < RuntimeErrorMyError79,1808
367
+ def test_and_raises_with_exception_class_throws_exceptiontest_and_raises_with_exception_class_throws_exception82,1846
368
+ def test_and_raises_with_arguments_throws_exception_made_with_argstest_and_raises_with_arguments_throws_exception_made_with_args91,2055
369
+ def test_and_raises_with_a_specific_exception_throws_the_exceptiontest_and_raises_with_a_specific_exception_throws_the_exception101,2336
370
+ def test_raises_is_an_alias_for_and_raisetest_raises_is_an_alias_for_and_raise112,2606
371
+ def test_multiple_expectationstest_multiple_expectations121,2811
372
+ def test_with_no_args_with_no_argstest_with_no_args_with_no_args131,3048
373
+ def test__with_no_args_but_with_argstest__with_no_args_but_with_args138,3176
374
+ def test_with_any_argstest_with_any_args147,3376
375
+ def test_with_any_single_arg_matchingtest_with_any_single_arg_matching157,3554
376
+ def test_with_any_single_arg_nonmatchingtest_with_any_single_arg_nonmatching165,3747
377
+ def test_with_equal_arg_matchingtest_with_equal_arg_matching175,3982
378
+ def test_with_equal_arg_nonmatchingtest_with_equal_arg_nonmatching182,4145
379
+ def test_with_arbitrary_arg_matchingtest_with_arbitrary_arg_matching191,4382
380
+ def test_args_matching_with_regextest_args_matching_with_regex206,4802
381
+ def test_arg_matching_with_regex_matching_non_stringtest_arg_matching_with_regex_matching_non_string218,5129
382
+ def test_arg_matching_with_classtest_arg_matching_with_class225,5306
383
+ def test_arg_matching_with_no_matchtest_arg_matching_with_no_match236,5596
384
+ def test_arg_matching_with_string_doesnt_over_matchtest_arg_matching_with_string_doesnt_over_match245,5809
385
+ def test_block_arg_given_to_no_argstest_block_arg_given_to_no_args254,6028
386
+ def test_block_arg_given_to_matching_proctest_block_arg_given_to_matching_proc263,6232
387
+ def test_arg_matching_precedence_when_best_firsttest_arg_matching_precedence_when_best_first274,6517
388
+ def test_arg_matching_precedence_when_best_last_but_still_matches_firsttest_arg_matching_precedence_when_best_last_but_still_matches_first282,6726
389
+ def test_never_and_never_calledtest_never_and_never_called290,6958
390
+ def test_never_and_called_oncetest_never_and_called_once296,7073
391
+ def test_once_called_oncetest_once_called_once305,7269
392
+ def test_once_but_never_calledtest_once_but_never_called312,7403
393
+ def test_once_but_called_twicetest_once_but_called_twice320,7590
394
+ def test_twice_and_called_twicetest_twice_and_called_twice330,7809
395
+ def test_zero_or_more_called_zerotest_zero_or_more_called_zero338,7964
396
+ def test_zero_or_more_called_oncetest_zero_or_more_called_once344,8086
397
+ def test_zero_or_more_called_100test_zero_or_more_called_100351,8219
398
+ def test_timestest_times358,8365
399
+ def test_at_least_called_oncetest_at_least_called_once365,8506
400
+ def test_at_least_but_never_calledtest_at_least_but_never_called372,8653
401
+ def test_at_least_once_but_called_twicetest_at_least_once_but_called_twice380,8856
402
+ def test_at_least_and_exacttest_at_least_and_exact388,9027
403
+ def test_at_most_but_never_calledtest_at_most_but_never_called398,9257
404
+ def test_at_most_called_oncetest_at_most_called_once404,9393
405
+ def test_at_most_called_twicetest_at_most_called_twice411,9538
406
+ def test_at_most_and_at_least_called_nevertest_at_most_and_at_least_called_never421,9766
407
+ def test_at_most_and_at_least_called_oncetest_at_most_and_at_least_called_once429,9991
408
+ def test_at_most_and_at_least_called_twicetest_at_most_and_at_least_called_twice436,10164
409
+ def test_at_most_and_at_least_called_three_timestest_at_most_and_at_least_called_three_times444,10352
410
+ def test_call_counts_only_apply_to_matching_argstest_call_counts_only_apply_to_matching_args455,10630
411
+ def test_call_counts_only_apply_to_matching_args_with_mismatchtest_call_counts_only_apply_to_matching_args_with_mismatch467,10908
412
+ def test_ordered_calls_in_ordertest_ordered_calls_in_order483,11341
413
+ def test_ordered_calls_out_of_ordertest_ordered_calls_out_of_order493,11513
414
+ def test_order_calls_with_different_arg_lists_and_in_ordertest_order_calls_with_different_arg_lists_and_in_order505,11764
415
+ def test_order_calls_with_different_arg_lists_and_out_of_ordertest_order_calls_with_different_arg_lists_and_out_of_order515,12007
416
+ def test_unordered_calls_do_not_effect_ordered_testingtest_unordered_calls_do_not_effect_ordered_testing527,12323
417
+ def test_ordered_with_multiple_calls_is_oktest_ordered_with_multiple_calls_is_ok541,12593
418
+ def test_grouped_ordering_with_numberstest_grouped_ordering_with_numbers553,12804
419
+ def test_grouped_ordering_with_symbolstest_grouped_ordering_with_symbols568,13125
420
+ def test_explicit_ordering_mixed_with_implicit_ordering_should_not_overlaptest_explicit_ordering_mixed_with_implicit_ordering_should_not_overlap583,13487
421
+ def test_explicit_ordering_with_explicit_misorderstest_explicit_ordering_with_explicit_misorders593,13860
422
+ def test_ordering_with_explicit_no_args_matches_correctlytest_ordering_with_explicit_no_args_matches_correctly609,14391
423
+ def test_ordering_with_any_arg_matching_correctly_matchestest_ordering_with_any_arg_matching_correctly_matches621,14768
424
+ def test_expectation_formatingtest_expectation_formating632,15082
425
+ def test_multi_expectation_formattingtest_multi_expectation_formatting637,15266
426
+ def test_explicit_ordering_with_limits_allow_multiple_return_valuestest_explicit_ordering_with_limits_allow_multiple_return_values642,15409
427
+ def test_global_methods_can_be_mockedtest_global_methods_can_be_mocked661,16120
428
+ def test_kernel_methods_can_be_mockedtest_kernel_methods_can_be_mocked667,16308
429
+ def test_undefing_kernel_methods_dont_effect_other_mockstest_undefing_kernel_methods_dont_effect_other_mocks673,16490
430
+ def assert_failure(message=nil)assert_failure684,16920
431
+ class TestFlexMockShouldsWithInclude < Test::Unit::TestCaseTestFlexMockShouldsWithInclude698,17270
432
+ def test_include_enables_unqualified_arg_type_referencestest_include_enables_unqualified_arg_type_references700,17364
433
+ class TestFlexMockArgTypesDontLeak < Test::Unit::TestCaseTestFlexMockArgTypesDontLeak708,17528
434
+ def test_unqualified_arg_type_references_are_undefined_by_defaulttest_unqualified_arg_type_references_are_undefined_by_default709,17586
435
+
436
+ test/test_tu_integration.rb,1570
437
+ class TestTuIntegrationFlexMockMethod < Test::Unit::TestCaseTestTuIntegrationFlexMockMethod15,352
438
+ def test_can_construct_flexmocktest_can_construct_flexmock18,445
439
+ def test_can_construct_flexmock_with_blocktest_can_construct_flexmock_with_block24,594
440
+ class TestTuIntegrationMockVerificationInTeardown < Test::Unit::TestCaseTestTuIntegrationMockVerificationInTeardown32,770
441
+ def teardownteardown35,873
442
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown41,969
443
+ class TestTuIntegrationMockVerificationWithoutSetup < Test::Unit::TestCaseTestTuIntegrationMockVerificationWithoutSetup46,1087
444
+ def teardownteardown49,1192
445
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown55,1288
446
+ class TestTuIntegrationMockVerificationForgetfulSetup < Test::Unit::TestCaseTestTuIntegrationMockVerificationForgetfulSetup60,1406
447
+ def teardownteardown63,1513
448
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown69,1609
449
+ class TestTuIntegrationSetupOverridenAndNoMocksOk < Test::Unit::TestCaseTestTuIntegrationSetupOverridenAndNoMocksOk74,1727
450
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown77,1830
451
+ class TestTuIntegrationFailurePreventsVerification < Test::Unit::TestCaseTestTuIntegrationFailurePreventsVerification81,1893
452
+ def test_mock_verification_occurs_during_teardowntest_mock_verification_occurs_during_teardown84,1997
453
+ def simulate_failuresimulate_failure91,2131
454
+
455
+ test/rspec_integration/integration_spec.rb,0
456
+
457
+ test/test_unit_integration/test_auto_test_unit.rb,263
458
+ class TestFlexmockTestUnit < Test::Unit::TestCaseTestFlexmockTestUnit17,387
459
+ def teardownteardown18,437
460
+ def test_can_create_mockstest_can_create_mocks23,496
461
+ def test_should_fail__mocks_are_auto_verifiedtest_should_fail__mocks_are_auto_verified30,641
@@ -0,0 +1,111 @@
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.3
7
+
8
+ * Added the flexmodel() method for better support when mocking
9
+ ActiveRecord objects. flexmodel(YourModelClass) will return a pure
10
+ mock object that responds to some basic ActiveRecord methods with
11
+ reasonable defaults. The flexmodel() method is optional and you
12
+ need to require 'flexmock/activerecord' to active it.
13
+
14
+ * The flexmock() method now _always_ returns a combination domain
15
+ object / mock object. This means the object return can handle
16
+ domain methods and mock-specific methods (such as should_receive and
17
+ mock_teardown).
18
+
19
+ * A side effect of always returning a domain/mock object is that
20
+ partial mocks are now enhanced with about 5 or 6 extra methods.
21
+ Since partial mocks are real objects with just a few methods mocked,
22
+ there is a (small) potential for a method name conflict. FlexMock
23
+ now supports a safe-mode for partial mocks if this is an issue in
24
+ particular case (see the RDoc README file for more details).
25
+
26
+ * Fixed a small bug where attempting to mock a method that the partial
27
+ mock claims to respond to, but doesn't actually have defined would
28
+ cause an error. This tended to happen on active record objects
29
+ where attributes are dynamically handled.
30
+
31
+ == What is FlexMock?
32
+
33
+ FlexMock is a flexible framework for creating mock object for testing. When
34
+ running unit tests, it is often desirable to use isolate the objects being
35
+ tested from the "real world" by having them interact with simplified test
36
+ objects. Sometimes these test objects simply return values when called, other
37
+ times they verify that certain methods were called with particular arguments
38
+ in a particular order.
39
+
40
+ FlexMock makes creating these test objects easy.
41
+
42
+ === Features
43
+
44
+ * Easy integration with both Test::Unit and RSpec. Mocks created with the
45
+ flexmock method are automatically verified at the end of the test or
46
+ example.
47
+
48
+ * A fluent interface that allows mock behavior to be specified very
49
+ easily.
50
+
51
+ * A "record mode" where an existing implementation can record its
52
+ interaction with a mock for later validation against a new
53
+ implementation.
54
+
55
+ * Easy mocking of individual methods in existing, non-mock objects.
56
+
57
+ * The ability to cause classes to instantiate test instances (instead of real
58
+ instances) for the duration of a test.
59
+
60
+ === Example
61
+
62
+ Suppose you had a Dog object that wagged a tail when it was happy.
63
+ Something like this:
64
+
65
+ class Dog
66
+ def initialize(a_tail)
67
+ @tail = a_tail
68
+ end
69
+ def happy
70
+ @tail.wag
71
+ end
72
+ end
73
+
74
+ To test the +Dog+ class without a real +Tail+ object (perhaps because
75
+ real +Tail+ objects activate servos in some robotic equipment), you
76
+ can do something like this:
77
+
78
+ require 'test/unit'
79
+ require 'flexmock/test_unit'
80
+
81
+ class TestDog < Test::Unit::TestCase
82
+ def test_dog_wags_tail_when_happy
83
+ tail = flexmock("tail")
84
+ tail.should_receive(:wag).once
85
+ dog = Dog.new(tail)
86
+ dog.happy
87
+ end
88
+ end
89
+
90
+ FlexMock will automatically verify that the mocked tail object received the
91
+ message +wag+ exactly one time. If it doesn't, the test will not pass.
92
+
93
+ See the FlexMock documentation at http://flexmock.rubyforge.org for details on
94
+ specifying arguments and return values on mocked methods, as well as a simple
95
+ technique for mocking tail objects when the Dog class creates the tail objects
96
+ directly.
97
+
98
+ == Availability
99
+
100
+ You can make sure you have the latest version with a quick RubyGems command:
101
+
102
+ gem install flexmock (you may need root/admin privileges)
103
+
104
+ Otherwise, you can get it from the more traditional places:
105
+
106
+ Download:: http://rubyforge.org/project/showfiles.php?group_id=170
107
+
108
+ You will find documentation at: http://flexmock.rubyforge.org.
109
+
110
+ -- Jim Weirich
111
+
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'flexmock'
4
+
5
+ class FlexMock
6
+ module MockContainer
7
+ def MockContainer.next_id
8
+ @id_counter ||= 0
9
+ @id_counter += 1
10
+ end
11
+
12
+ def flexmodel(model_class, *args, &block)
13
+ id = MockContainer.next_id
14
+ mock = flexmock("#{model_class}_#{id}", *args, &block)
15
+ mock.should_receive(
16
+ :id => id,
17
+ :to_params => id.to_s,
18
+ :new_record? => false,
19
+ :errors => flexmock("errors", :count => 0),
20
+ :class => model_class)
21
+ mock.should_receive(:is_a?).with(any).and_return { |other|
22
+ other == model_class
23
+ }
24
+ mock
25
+ end
26
+ end
27
+ end
data/lib/flexmock/core.rb CHANGED
@@ -42,6 +42,11 @@ require 'flexmock/composite'
42
42
  # call +super+.
43
43
  #
44
44
  class FlexMock
45
+
46
+ # Error raised when flexmock is used incorrectly.
47
+ class UsageError < RuntimeError
48
+ end
49
+
45
50
  attr_reader :mock_name, :mock_groups
46
51
  attr_accessor :mock_current_order, :mock_container
47
52
 
@@ -202,4 +207,4 @@ class FlexMock
202
207
  end
203
208
  end
204
209
 
205
- require 'flexmock/core_class_methods'
210
+ require 'flexmock/core_class_methods'
@@ -113,10 +113,11 @@ class FlexMock
113
113
  name = nil
114
114
  quick_defs = {}
115
115
  domain_obj = nil
116
+ safe_mode = false
116
117
  while ! args.empty?
117
118
  case args.first
118
- when :base
119
- args.shift
119
+ when :base, :safe
120
+ safe_mode = (args.shift == :safe)
120
121
  domain_obj = args.shift
121
122
  when String, Symbol
122
123
  name = args.shift.to_s
@@ -126,8 +127,10 @@ class FlexMock
126
127
  domain_obj = args.shift
127
128
  end
128
129
  end
130
+ raise UsageError, "a block is required in safe mode" if safe_mode && ! block_given?
131
+
129
132
  if domain_obj
130
- mock = flexmock_make_partial_proxy(domain_obj, name)
133
+ mock = flexmock_make_partial_proxy(domain_obj, name, safe_mode)
131
134
  else
132
135
  mock = FlexMock.new(name || "unknown")
133
136
  domain_obj = mock
@@ -136,17 +139,18 @@ class FlexMock
136
139
  yield(mock) if block_given?
137
140
  flexmock_remember(mock)
138
141
  block_given? ? domain_obj : mock
142
+ domain_obj
139
143
  end
140
144
  alias flexstub flexmock
141
145
 
142
146
  private
143
147
 
144
- # Create a PartialMock for the given object. Use +name+ as the name
145
- # of the mock object.
146
- def flexmock_make_partial_proxy(obj, name)
148
+ # Create a PartialMockProxy for the given object. Use +name+ as
149
+ # the name of the mock object.
150
+ def flexmock_make_partial_proxy(obj, name, safe_mode)
147
151
  name ||= "flexmock(#{obj.class.to_s})"
148
152
  obj.instance_eval {
149
- @flexmock_proxy ||= PartialMock.new(obj, FlexMock.new(name))
153
+ @flexmock_proxy ||= PartialMockProxy.new(obj, FlexMock.new(name), safe_mode)
150
154
  }
151
155
  obj.instance_variable_get("@flexmock_proxy")
152
156
  end
@@ -14,20 +14,29 @@ require 'flexmock/noop'
14
14
  class FlexMock
15
15
 
16
16
  # #########################################################################
17
- # PartialMock is used to mate the mock framework to an existing object. The
18
- # object is "enhanced" with a reference to a mock object (stored in
19
- # <tt>@flexmock_mock</tt>). When the +should_receive+ method is sent to the
20
- # proxy, it overrides the existing object's method by creating singleton
21
- # method that forwards to the mock. When testing is complete, PartialMock
22
- # will erase the mocking infrastructure from the object being mocked (e.g.
23
- # remove instance variables and mock singleton methods).
17
+ # PartialMockProxy is used to mate the mock framework to an existing
18
+ # object. The object is "enhanced" with a reference to a mock
19
+ # object (stored in <tt>@flexmock_mock</tt>). When the
20
+ # +should_receive+ method is sent to the proxy, it overrides the
21
+ # existing object's method by creating singleton method that
22
+ # forwards to the mock. When testing is complete, PartialMockProxy
23
+ # will erase the mocking infrastructure from the object being mocked
24
+ # (e.g. remove instance variables and mock singleton methods).
24
25
  #
25
- class PartialMock
26
+ class PartialMockProxy
26
27
  attr_reader :mock, :mock_groups
27
28
  attr_accessor :mock_current_order, :mock_container
28
29
 
29
- # Initialize a PartialMock object.
30
- def initialize(obj, mock)
30
+ # The following methods are added to partial mocks so that they
31
+ # can act like a mock.
32
+
33
+ MOCK_METHODS = [
34
+ :should_receive, :new_instances, :any_instance,
35
+ :mock, :mock_teardown, :mock_verify
36
+ ]
37
+
38
+ # Initialize a PartialMockProxy object.
39
+ def initialize(obj, mock, safe_mode)
31
40
  @obj = obj
32
41
  @mock = mock
33
42
  @method_definitions = {}
@@ -35,6 +44,11 @@ class FlexMock
35
44
  @allocated_order = 0
36
45
  @mock_current_order = 0
37
46
  @mock_groups = {}
47
+ unless safe_mode
48
+ MOCK_METHODS.each do |sym|
49
+ add_mock_method(@obj, sym)
50
+ end
51
+ end
38
52
  end
39
53
 
40
54
  # :call-seq:
@@ -61,7 +75,6 @@ class FlexMock
61
75
  FlexMock.should_receive(args) do |sym|
62
76
  unless @methods_proxied.include?(sym)
63
77
  hide_existing_method(sym)
64
- @methods_proxied << sym
65
78
  end
66
79
  ex = @mock.should_receive(sym)
67
80
  ex.mock = self
@@ -69,6 +82,15 @@ class FlexMock
69
82
  end
70
83
  end
71
84
 
85
+ def add_mock_method(obj, method_name)
86
+ stow_existing_definition(method_name)
87
+ eval %{
88
+ def obj.#{method_name}(*args, &block)
89
+ @flexmock_proxy.#{method_name}(*args, &block)
90
+ end
91
+ }
92
+ end
93
+
72
94
  # :call-seq:
73
95
  # new_instances.should_receive(...)
74
96
  # new_instances { |instance| instance.should_receive(...) }
@@ -146,7 +168,7 @@ class FlexMock
146
168
  class << @obj; self; end
147
169
  end
148
170
 
149
- # Is the current method a singleton method in the object we are
171
+ # Is the given method name a singleton method in the object we are
150
172
  # mocking?
151
173
  def singleton?(method_name)
152
174
  @obj.methods(false).include?(method_name.to_s)
@@ -159,13 +181,16 @@ class FlexMock
159
181
  # not a singleton, all we need to do is override it with our own
160
182
  # singleton.
161
183
  def hide_existing_method(method_name)
162
- if @obj.respond_to?(method_name)
163
- new_alias = new_name(method_name)
164
- unless @obj.respond_to?(new_alias)
165
- sclass.class_eval do
166
- alias_method(new_alias, method_name)
167
- end
168
- end
184
+ stow_existing_definition(method_name)
185
+ define_proxy_method(method_name)
186
+ end
187
+
188
+ # Stow the existing method definition so that it can be recovered
189
+ # later.
190
+ def stow_existing_definition(method_name)
191
+ @methods_proxied << method_name
192
+ new_alias = create_alias_for_existing_method(method_name)
193
+ if new_alias
169
194
  my_object = @obj
170
195
  @method_definitions[method_name] = Proc.new { |*args|
171
196
  block = nil
@@ -177,7 +202,24 @@ class FlexMock
177
202
  }
178
203
  end
179
204
  remove_current_method(method_name) if singleton?(method_name)
180
- define_proxy_method(method_name)
205
+ end
206
+
207
+ # Create an alias for the existing +method_name+. Returns the new
208
+ # alias name. If the aliasing process fails (because the method
209
+ # doesn't really exist, then return nil.
210
+ def create_alias_for_existing_method(method_name)
211
+ begin
212
+ new_alias = new_name(method_name)
213
+ unless @obj.respond_to?(new_alias)
214
+ sclass.class_eval do
215
+ alias_method(new_alias, method_name)
216
+ end
217
+ end
218
+ new_alias
219
+ rescue NameError => ex
220
+ # Alias attempt failed
221
+ nil
222
+ end
181
223
  end
182
224
 
183
225
  # Define a proxy method that forwards to our mock object. The
@@ -185,17 +227,20 @@ class FlexMock
185
227
  # being mocked.
186
228
  def define_proxy_method(method_name)
187
229
  if method_name.to_s =~ /=$/
230
+ eval_line = __LINE__ + 1
188
231
  sclass.class_eval %{
189
232
  def #{method_name}(*args, &block)
190
233
  @flexmock_proxy.mock.__send__(:#{method_name}, *args, &block)
191
234
  end
192
- }
235
+ }, __FILE__, eval_line
193
236
  else
237
+ eval_line = __LINE__ + 1
194
238
  sclass.class_eval %{
195
239
  def #{method_name}(*args, &block)
196
240
  @flexmock_proxy.mock.#{method_name}(*args, &block)
197
241
  end
198
- }
242
+ }, __FILE__, eval_line
243
+ make_rcov_recognize_the_above_eval_is_covered = true
199
244
  end
200
245
  end
201
246
 
@@ -33,4 +33,4 @@ context "FlexMock in a RSpec example" do
33
33
  specify "Should show an example failure" do
34
34
  1.should == 2
35
35
  end
36
- end
36
+ end
@@ -102,7 +102,7 @@ class TestFlexmockContainerMethods < Test::Unit::TestCase
102
102
  assert_equal 2, s.length
103
103
  end
104
104
 
105
- def test_multiple_stubs_work_with_same_PartialMock
105
+ def test_multiple_stubs_work_with_same_partial_mock_proxy
106
106
  obj = Object.new
107
107
  mock1 = flexmock(obj)
108
108
  mock2 = flexmock(obj)
@@ -116,4 +116,4 @@ class TestFlexmockContainerMethods < Test::Unit::TestCase
116
116
  assert_equal :lo, obj.hi
117
117
  assert_equal :low, obj.high
118
118
  end
119
- end
119
+ end
@@ -58,7 +58,7 @@ class TestExtendedShouldReceiveOnFullMocks < Test::Unit::TestCase
58
58
 
59
59
  end
60
60
 
61
- class TestExtendedShouldReceiveOnPartialMocks < Test::Unit::TestCase
61
+ class TestExtendedShouldReceiveOnPartialMockProxies < Test::Unit::TestCase
62
62
  include FlexMock::TestCase
63
63
  include ExtendedShouldReceiveTests
64
64
 
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'flexmock/activerecord'
5
+
6
+ class DummyModel
7
+ end
8
+
9
+ ######################################################################
10
+ class TestFlexModel < Test::Unit::TestCase
11
+ include FlexMock::TestCase
12
+
13
+ def test_initial_conditions
14
+ model = flexmodel(DummyModel)
15
+ assert_match(/^DummyModel_\d+/, model.mock_name)
16
+ assert_equal model.id.to_s, model.to_params
17
+ assert ! model.new_record?
18
+ assert model.is_a?(DummyModel)
19
+ assert_equal DummyModel, model.class
20
+ end
21
+
22
+ def test_mock_models_have_different_ids
23
+ m1 = flexmodel(DummyModel)
24
+ m2 = flexmodel(DummyModel)
25
+ assert m2.id != m1.id
26
+ end
27
+
28
+ def test_mock_models_can_have_quick_defs
29
+ model = flexmodel(DummyModel, :xyzzy => :ok)
30
+ assert_equal :ok, model.xyzzy
31
+ end
32
+
33
+ def test_mock_models_can_have_blocks
34
+ model = flexmodel(DummyModel) do |m|
35
+ m.should_receive(:xyzzy => :okdokay)
36
+ end
37
+ assert_equal :okdokay, model.xyzzy
38
+ end
39
+ end
40
+
@@ -214,5 +214,101 @@ class TestStubbing < Test::Unit::TestCase
214
214
  end
215
215
  assert_equal :growl, dog.bark
216
216
  end
217
+
218
+ def test_partial_mocks_always_return_domain_object
219
+ dog = Dog.new
220
+ assert_equal dog, flexmock(dog)
221
+ assert_equal dog, flexmock(dog) { }
222
+ end
223
+
224
+ MOCK_METHOD_SUBSET = [
225
+ :should_receive, :new_instances,
226
+ :mock, :mock_teardown, :mock_verify,
227
+ ]
228
+
229
+ def test_domain_objects_do_not_have_mock_methods
230
+ dog = Dog.new
231
+ MOCK_METHOD_SUBSET.each do |sym|
232
+ assert ! dog.respond_to?(sym), "should not have :#{sym} defined"
233
+ end
234
+ end
235
+
236
+ def test_partial_mocks_have_mock_methods
237
+ dog = Dog.new
238
+ flexmock(dog)
239
+ MOCK_METHOD_SUBSET.each do |sym|
240
+ assert dog.respond_to?(sym), "should have :#{sym} defined"
241
+ end
242
+ end
243
+
244
+ def test_partial_mocks_do_not_have_mock_methods_after_teardown
245
+ dog = Dog.new
246
+ flexmock(dog)
247
+ dog.mock_teardown
248
+ MOCK_METHOD_SUBSET.each do |sym|
249
+ assert ! dog.respond_to?(sym), "should not have :#{sym} defined"
250
+ end
251
+ end
252
+
253
+ def test_partial_mocks_with_mock_method_singleton_colision_have_original_defs_restored
254
+ dog = Dog.new
255
+ def dog.mock() :original end
256
+ flexmock(dog)
257
+ dog.mock_teardown
258
+ assert_equal :original, dog.mock
259
+ end
260
+
261
+ class MockColision
262
+ def mock
263
+ :original
264
+ end
265
+ end
266
+
267
+ def test_partial_mocks_with_mock_method_non_singleton_colision_have_original_defs_restored
268
+ mc = MockColision.new
269
+ flexmock(mc)
270
+ mc.mock_teardown
271
+ assert_equal :original, mc.mock
272
+ end
273
+
274
+ def test_safe_partial_mocks_do_not_support_mock_methods
275
+ dog = Dog.new
276
+ flexmock(:safe, dog) { }
277
+ MOCK_METHOD_SUBSET.each do |sym|
278
+ assert ! dog.respond_to?(sym), "should not have :#{sym} defined"
279
+ end
280
+ end
281
+
282
+ def test_safe_partial_mocks_require_block
283
+ dog = Dog.new
284
+ ex = assert_raise(FlexMock::UsageError) { flexmock(:safe, dog) }
285
+ end
286
+
287
+ def test_safe_partial_mocks_are_actually_mocked
288
+ dog = flexmock(:safe, Dog.new) { |m| m.should_receive(:bark => :mocked) }
289
+ assert_equal :mocked, dog.bark
290
+ end
291
+
292
+ class Liar
293
+ def respond_to?(method_name)
294
+ sym = method_name.to_sym
295
+ if sym == :not_defined
296
+ true
297
+ else
298
+ super(method_name)
299
+ end
300
+ end
301
+ end
302
+
303
+ def test_liar_actually_lies
304
+ liar = Liar.new
305
+ assert liar.respond_to?(:not_defined)
306
+ end
307
+
308
+ def test_partial_mock_where_respond_to_is_true_yet_method_is_not_there
309
+ liar = Liar.new
310
+ flexmock(liar, :not_defined => :xyzzy)
311
+ assert_equal :xyzzy, liar.not_defined
312
+ end
217
313
 
218
314
  end
metadata CHANGED
@@ -3,8 +3,8 @@ 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.2
7
- date: 2007-06-27 00:00:00 -04:00
6
+ version: 0.6.3
7
+ date: 2007-08-16 00:00:00 -04:00
8
8
  summary: Simple and Flexible Mock Objects for Testing
9
9
  require_paths:
10
10
  - lib
@@ -29,10 +29,12 @@ post_install_message:
29
29
  authors:
30
30
  - Jim Weirich
31
31
  files:
32
- - CHANGELOG
32
+ - CHANGES
33
33
  - Rakefile
34
34
  - README
35
+ - TAGS
35
36
  - lib/flexmock.rb
37
+ - lib/flexmock/activerecord.rb
36
38
  - lib/flexmock/argument_matchers.rb
37
39
  - lib/flexmock/argument_types.rb
38
40
  - lib/flexmock/base.rb
@@ -54,6 +56,7 @@ files:
54
56
  - test/test_default_framework_adapter.rb
55
57
  - test/test_example.rb
56
58
  - test/test_extended_should_receive.rb
59
+ - test/test_flexmodel.rb
57
60
  - test/test_mock.rb
58
61
  - test/test_naming.rb
59
62
  - test/test_new_instances.rb
@@ -76,6 +79,7 @@ files:
76
79
  - doc/releases/flexmock-0.6.0.rdoc
77
80
  - doc/releases/flexmock-0.6.1.rdoc
78
81
  - doc/releases/flexmock-0.6.2.rdoc
82
+ - doc/releases/flexmock-0.6.3.rdoc
79
83
  test_files: []
80
84
 
81
85
  rdoc_options:
@@ -86,7 +90,7 @@ rdoc_options:
86
90
  - --line-numbers
87
91
  extra_rdoc_files:
88
92
  - README
89
- - CHANGELOG
93
+ - CHANGES
90
94
  - doc/GoogleExample.rdoc
91
95
  - doc/releases/flexmock-0.4.0.rdoc
92
96
  - doc/releases/flexmock-0.4.1.rdoc
@@ -97,6 +101,7 @@ extra_rdoc_files:
97
101
  - doc/releases/flexmock-0.6.0.rdoc
98
102
  - doc/releases/flexmock-0.6.1.rdoc
99
103
  - doc/releases/flexmock-0.6.2.rdoc
104
+ - doc/releases/flexmock-0.6.3.rdoc
100
105
  executables: []
101
106
 
102
107
  extensions: []