OLD | NEW |
| (Empty) |
1 //------------------------------------------------------------------------------
--------- | |
2 // $Id: OCMockObjectTests.m 74 2011-02-15 12:59:47Z erik $ | |
3 // Copyright (c) 2004-2010 by Mulle Kybernetik. See License file for details. | |
4 //------------------------------------------------------------------------------
--------- | |
5 | |
6 #import <OCMock/OCMock.h> | |
7 #import "OCMockObjectTests.h" | |
8 | |
9 // -----------------------------------------------------------------------------
--------- | |
10 // Helper classes and protocols for testing | |
11 // -----------------------------------------------------------------------------
--------- | |
12 | |
13 @protocol TestProtocol | |
14 - (int)primitiveValue; | |
15 @optional | |
16 - (id)objectValue; | |
17 @end | |
18 | |
19 @protocol ProtocolWithTypeQualifierMethod | |
20 - (void)aSpecialMethod:(byref in void *)someArg; | |
21 @end | |
22 | |
23 @interface TestClassThatCallsSelf : NSObject | |
24 - (NSString *)method1; | |
25 - (NSString *)method2; | |
26 @end | |
27 | |
28 @implementation TestClassThatCallsSelf | |
29 | |
30 - (NSString *)method1 | |
31 { | |
32 id retVal = [self method2]; | |
33 return retVal; | |
34 } | |
35 | |
36 - (NSString *)method2 | |
37 { | |
38 return @"Foo"; | |
39 } | |
40 | |
41 @end | |
42 | |
43 @interface TestObserver : NSObject | |
44 { | |
45 @public | |
46 NSNotification *notification; | |
47 } | |
48 | |
49 @end | |
50 | |
51 @implementation TestObserver | |
52 | |
53 - (void)dealloc | |
54 { | |
55 [[NSNotificationCenter defaultCenter] removeObserver:self]; | |
56 [notification release]; | |
57 [super dealloc]; | |
58 } | |
59 | |
60 - (void)receiveNotification:(NSNotification *)aNotification | |
61 { | |
62 notification = [aNotification retain]; | |
63 } | |
64 | |
65 @end | |
66 | |
67 static NSString *TestNotification = @"TestNotification"; | |
68 | |
69 | |
70 // -----------------------------------------------------------------------------
--------- | |
71 // setup | |
72 // -----------------------------------------------------------------------------
--------- | |
73 | |
74 | |
75 @implementation OCMockObjectTests | |
76 | |
77 - (void)setUp | |
78 { | |
79 mock = [OCMockObject mockForClass:[NSString class]]; | |
80 } | |
81 | |
82 | |
83 // -----------------------------------------------------------------------------
--------- | |
84 // accepting stubbed methods / rejecting methods not stubbed | |
85 // -----------------------------------------------------------------------------
--------- | |
86 | |
87 - (void)testAcceptsStubbedMethod | |
88 { | |
89 [[mock stub] lowercaseString]; | |
90 [mock lowercaseString]; | |
91 } | |
92 | |
93 - (void)testRaisesExceptionWhenUnknownMethodIsCalled | |
94 { | |
95 [[mock stub] lowercaseString]; | |
96 STAssertThrows([mock uppercaseString], @"Should have raised an exception
."); | |
97 } | |
98 | |
99 | |
100 - (void)testAcceptsStubbedMethodWithSpecificArgument | |
101 { | |
102 [[mock stub] hasSuffix:@"foo"]; | |
103 [mock hasSuffix:@"foo"]; | |
104 } | |
105 | |
106 | |
107 - (void)testAcceptsStubbedMethodWithConstraint | |
108 { | |
109 [[mock stub] hasSuffix:[OCMArg any]]; | |
110 [mock hasSuffix:@"foo"]; | |
111 [mock hasSuffix:@"bar"]; | |
112 } | |
113 | |
114 #if NS_BLOCKS_AVAILABLE | |
115 | |
116 - (void)testAcceptsStubbedMethodWithBlockArgument | |
117 { | |
118 mock = [OCMockObject mockForClass:[NSArray class]]; | |
119 [[mock stub] indexesOfObjectsPassingTest:[OCMArg any]]; | |
120 [mock indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop)
{ return YES; }]; | |
121 } | |
122 | |
123 | |
124 - (void)testAcceptsStubbedMethodWithBlockConstraint | |
125 { | |
126 [[mock stub] hasSuffix:[OCMArg checkWithBlock:^(id value) { return [valu
e isEqualToString:@"foo"]; }]]; | |
127 | |
128 STAssertNoThrow([mock hasSuffix:@"foo"], @"Should not have thrown a exce
ption"); | |
129 STAssertThrows([mock hasSuffix:@"bar"], @"Should have thrown a exception
"); | |
130 } | |
131 | |
132 #endif | |
133 | |
134 - (void)testAcceptsStubbedMethodWithNilArgument | |
135 { | |
136 [[mock stub] hasSuffix:nil]; | |
137 | |
138 [mock hasSuffix:nil]; | |
139 } | |
140 | |
141 - (void)testRaisesExceptionWhenMethodWithWrongArgumentIsCalled | |
142 { | |
143 [[mock stub] hasSuffix:@"foo"]; | |
144 STAssertThrows([mock hasSuffix:@"xyz"], @"Should have raised an exceptio
n."); | |
145 } | |
146 | |
147 | |
148 - (void)testAcceptsStubbedMethodWithScalarArgument | |
149 { | |
150 [[mock stub] stringByPaddingToLength:20 withString:@"foo" startingAtInde
x:5]; | |
151 [mock stringByPaddingToLength:20 withString:@"foo" startingAtIndex:5]; | |
152 } | |
153 | |
154 | |
155 - (void)testRaisesExceptionWhenMethodWithOneWrongScalarArgumentIsCalled | |
156 { | |
157 [[mock stub] stringByPaddingToLength:20 withString:@"foo" startingAtInde
x:5]; | |
158 STAssertThrows([mock stringByPaddingToLength:20 withString:@"foo" starti
ngAtIndex:3], @"Should have raised an exception."); | |
159 } | |
160 | |
161 - (void)testAcceptsStubbedMethodWithPointerArgument | |
162 { | |
163 NSError *error; | |
164 BOOL yes = YES; | |
165 [[[mock stub] andReturnValue:OCMOCK_VALUE(yes)] writeToFile:OCMOCK_ANY a
tomically:YES encoding:NSMacOSRomanStringEncoding error:&error]; | |
166 | |
167 STAssertTrue([mock writeToFile:@"foo" atomically:YES encoding:NSMacOSRom
anStringEncoding error:&error], nil); | |
168 } | |
169 | |
170 - (void)testAcceptsStubbedMethodWithAnyPointerArgument | |
171 { | |
172 BOOL yes = YES; | |
173 NSError *error; | |
174 [[[mock stub] andReturnValue:OCMOCK_VALUE(yes)] writeToFile:OCMOCK_ANY a
tomically:YES encoding:NSMacOSRomanStringEncoding error:[OCMArg anyPointer]]; | |
175 | |
176 STAssertTrue([mock writeToFile:@"foo" atomically:YES encoding:NSMacOSRom
anStringEncoding error:&error], nil); | |
177 } | |
178 | |
179 - (void)testRaisesExceptionWhenMethodWithWrongPointerArgumentIsCalled | |
180 { | |
181 NSString *string; | |
182 NSString *anotherString; | |
183 NSArray *array; | |
184 | |
185 [[mock stub] completePathIntoString:&string caseSensitive:YES matchesInt
oArray:&array filterTypes:OCMOCK_ANY]; | |
186 | |
187 STAssertThrows([mock completePathIntoString:&anotherString caseSensitive
:YES matchesIntoArray:&array filterTypes:OCMOCK_ANY], nil); | |
188 } | |
189 | |
190 - (void)testAcceptsStubbedMethodWithVoidPointerArgument | |
191 { | |
192 mock = [OCMockObject mockForClass:[NSMutableData class]]; | |
193 [[mock stub] appendBytes:NULL length:0]; | |
194 [mock appendBytes:NULL length:0]; | |
195 } | |
196 | |
197 | |
198 - (void)testRaisesExceptionWhenMethodWithWrongVoidPointerArgumentIsCalled | |
199 { | |
200 mock = [OCMockObject mockForClass:[NSMutableData class]]; | |
201 [[mock stub] appendBytes:"foo" length:3]; | |
202 STAssertThrows([mock appendBytes:"bar" length:3], @"Should have raised a
n exception."); | |
203 } | |
204 | |
205 | |
206 - (void)testAcceptsStubbedMethodWithPointerPointerArgument | |
207 { | |
208 NSError *error = nil; | |
209 [[mock stub] initWithContentsOfFile:@"foo.txt" encoding:NSASCIIStringEnc
oding error:&error]; | |
210 [mock initWithContentsOfFile:@"foo.txt" encoding:NSASCIIStringEncoding e
rror:&error]; | |
211 } | |
212 | |
213 | |
214 - (void)testRaisesExceptionWhenMethodWithWrongPointerPointerArgumentIsCalled | |
215 { | |
216 NSError *error = nil, *error2; | |
217 [[mock stub] initWithContentsOfFile:@"foo.txt" encoding:NSASCIIStringEnc
oding error:&error]; | |
218 STAssertThrows([mock initWithContentsOfFile:@"foo.txt" encoding:NSASCIIS
tringEncoding error:&error2], @"Should have raised."); | |
219 } | |
220 | |
221 | |
222 - (void)testAcceptsStubbedMethodWithStructArgument | |
223 { | |
224 NSRange range = NSMakeRange(0,20); | |
225 [[mock stub] substringWithRange:range]; | |
226 [mock substringWithRange:range]; | |
227 } | |
228 | |
229 | |
230 - (void)testRaisesExceptionWhenMethodWithWrongStructArgumentIsCalled | |
231 { | |
232 NSRange range = NSMakeRange(0,20); | |
233 NSRange otherRange = NSMakeRange(0,10); | |
234 [[mock stub] substringWithRange:range]; | |
235 STAssertThrows([mock substringWithRange:otherRange], @"Should have raise
d an exception."); | |
236 } | |
237 | |
238 | |
239 - (void)testCanPassMocksAsArguments | |
240 { | |
241 id mockArg = [OCMockObject mockForClass:[NSString class]]; | |
242 [[mock stub] stringByAppendingString:[OCMArg any]]; | |
243 [mock stringByAppendingString:mockArg]; | |
244 } | |
245 | |
246 - (void)testCanStubWithMockArguments | |
247 { | |
248 id mockArg = [OCMockObject mockForClass:[NSString class]]; | |
249 [[mock stub] stringByAppendingString:mockArg]; | |
250 [mock stringByAppendingString:mockArg]; | |
251 } | |
252 | |
253 - (void)testRaisesExceptionWhenStubbedMockArgIsNotUsed | |
254 { | |
255 id mockArg = [OCMockObject mockForClass:[NSString class]]; | |
256 [[mock stub] stringByAppendingString:mockArg]; | |
257 STAssertThrows([mock stringByAppendingString:@"foo"], @"Should have rais
ed an exception."); | |
258 } | |
259 | |
260 - (void)testRaisesExceptionWhenDifferentMockArgumentIsPassed | |
261 { | |
262 id expectedArg = [OCMockObject mockForClass:[NSString class]]; | |
263 id otherArg = [OCMockObject mockForClass:[NSString class]]; | |
264 [[mock stub] stringByAppendingString:otherArg]; | |
265 STAssertThrows([mock stringByAppendingString:expectedArg], @"Should have
raised an exception."); | |
266 } | |
267 | |
268 | |
269 // -----------------------------------------------------------------------------
--------- | |
270 // returning values from stubbed methods | |
271 // -----------------------------------------------------------------------------
--------- | |
272 | |
273 - (void)testReturnsStubbedReturnValue | |
274 { | |
275 id returnValue; | |
276 | |
277 [[[mock stub] andReturn:@"megamock"] lowercaseString]; | |
278 returnValue = [mock lowercaseString]; | |
279 | |
280 STAssertEqualObjects(@"megamock", returnValue, @"Should have returned st
ubbed value."); | |
281 | |
282 } | |
283 | |
284 - (void)testReturnsStubbedIntReturnValue | |
285 { | |
286 int expectedValue = 42; | |
287 [[[mock stub] andReturnValue:OCMOCK_VALUE(expectedValue)] intValue]; | |
288 int returnValue = [mock intValue]; | |
289 | |
290 STAssertEquals(expectedValue, returnValue, @"Should have returned stubbe
d value."); | |
291 } | |
292 | |
293 - (void)testRaisesWhenBoxedValueTypesDoNotMatch | |
294 { | |
295 double expectedValue = 42; | |
296 [[[mock stub] andReturnValue:OCMOCK_VALUE(expectedValue)] intValue]; | |
297 | |
298 STAssertThrows([mock intValue], @"Should have raised an exception."); | |
299 } | |
300 | |
301 - (void)testReturnsStubbedNilReturnValue | |
302 { | |
303 [[[mock stub] andReturn:nil] uppercaseString]; | |
304 | |
305 id returnValue = [mock uppercaseString]; | |
306 | |
307 STAssertNil(returnValue, @"Should have returned stubbed value, which is
nil."); | |
308 } | |
309 | |
310 | |
311 // -----------------------------------------------------------------------------
--------- | |
312 // raising exceptions, posting notifications, etc. | |
313 // -----------------------------------------------------------------------------
--------- | |
314 | |
315 - (void)testRaisesExceptionWhenAskedTo | |
316 { | |
317 NSException *exception = [NSException exceptionWithName:@"TestException"
reason:@"test" userInfo:nil]; | |
318 [[[mock expect] andThrow:exception] lowercaseString]; | |
319 | |
320 STAssertThrows([mock lowercaseString], @"Should have raised an exception
."); | |
321 } | |
322 | |
323 - (void)testPostsNotificationWhenAskedTo | |
324 { | |
325 TestObserver *observer = [[[TestObserver alloc] init] autorelease]; | |
326 [[NSNotificationCenter defaultCenter] addObserver:observer selector:@sel
ector(receiveNotification:) name:TestNotification object:nil]; | |
327 | |
328 NSNotification *notification = [NSNotification notificationWithName:Test
Notification object:self]; | |
329 [[[mock stub] andPost:notification] lowercaseString]; | |
330 | |
331 [mock lowercaseString]; | |
332 | |
333 STAssertNotNil(observer->notification, @"Should have sent a notification
."); | |
334 STAssertEqualObjects(TestNotification, [observer->notification name], @"
Name should match posted one."); | |
335 STAssertEqualObjects(self, [observer->notification object], @"Object sho
uld match posted one."); | |
336 } | |
337 | |
338 - (void)testPostsNotificationInAddtionToReturningValue | |
339 { | |
340 TestObserver *observer = [[[TestObserver alloc] init] autorelease]; | |
341 [[NSNotificationCenter defaultCenter] addObserver:observer selector:@sel
ector(receiveNotification:) name:TestNotification object:nil]; | |
342 | |
343 NSNotification *notification = [NSNotification notificationWithName:Test
Notification object:self]; | |
344 [[[[mock stub] andReturn:@"foo"] andPost:notification] lowercaseString]; | |
345 | |
346 STAssertEqualObjects(@"foo", [mock lowercaseString], @"Should have retur
ned stubbed value."); | |
347 STAssertNotNil(observer->notification, @"Should have sent a notification
."); | |
348 } | |
349 | |
350 | |
351 - (NSString *)valueForString:(NSString *)aString andMask:(NSStringCompareOptions
)mask | |
352 { | |
353 return [NSString stringWithFormat:@"[%@, %d]", aString, mask]; | |
354 } | |
355 | |
356 - (void)testCallsAlternativeMethodAndPassesOriginalArgumentsAndReturnsValue | |
357 { | |
358 [[[mock stub] andCall:@selector(valueForString:andMask:) onObject:self]
commonPrefixWithString:@"FOO" options:NSCaseInsensitiveSearch]; | |
359 | |
360 NSString *returnValue = [mock commonPrefixWithString:@"FOO" options:NSCa
seInsensitiveSearch]; | |
361 | |
362 STAssertEqualObjects(@"[FOO, 1]", returnValue, @"Should have passed and
returned invocation."); | |
363 } | |
364 | |
365 #if NS_BLOCKS_AVAILABLE | |
366 | |
367 - (void)testCallsBlockWhichCanSetUpReturnValue | |
368 { | |
369 void (^theBlock)(NSInvocation *) = ^(NSInvocation *invocation) | |
370 { | |
371 NSString *value; | |
372 [invocation getArgument:&value atIndex:2]; | |
373 value = [NSString stringWithFormat:@"MOCK %@", value]; | |
374 [invocation setReturnValue:&value]; | |
375 }; | |
376 | |
377 [[[mock stub] andDo:theBlock] stringByAppendingString:[OCMArg any]]; | |
378 | |
379 STAssertEqualObjects(@"MOCK foo", [mock stringByAppendingString:@"foo"],
@"Should have called block."); | |
380 STAssertEqualObjects(@"MOCK bar", [mock stringByAppendingString:@"bar"],
@"Should have called block."); | |
381 } | |
382 | |
383 #endif | |
384 | |
385 - (void)testThrowsWhenTryingToUseForwardToRealObjectOnNonPartialMock | |
386 { | |
387 STAssertThrows([[[mock expect] andForwardToRealObject] method2], @"Shoul
d have raised and exception."); | |
388 } | |
389 | |
390 - (void)testForwardsToRealObjectWhenSetUpAndCalledOnMock | |
391 { | |
392 TestClassThatCallsSelf *realObject = [[[TestClassThatCallsSelf alloc] in
it] autorelease]; | |
393 mock = [OCMockObject partialMockForObject:realObject]; | |
394 | |
395 [[[mock expect] andForwardToRealObject] method2]; | |
396 STAssertEquals(@"Foo", [mock method2], @"Should have called method on re
al object."); | |
397 | |
398 [mock verify]; | |
399 } | |
400 | |
401 - (void)testForwardsToRealObjectWhenSetUpAndCalledOnRealObject | |
402 { | |
403 TestClassThatCallsSelf *realObject = [[[TestClassThatCallsSelf alloc] in
it] autorelease]; | |
404 mock = [OCMockObject partialMockForObject:realObject]; | |
405 | |
406 [[[mock expect] andForwardToRealObject] method2]; | |
407 STAssertEquals(@"Foo", [realObject method2], @"Should have called method
on real object."); | |
408 | |
409 [mock verify]; | |
410 } | |
411 | |
412 | |
413 // -----------------------------------------------------------------------------
--------- | |
414 // returning values in pass-by-reference arguments | |
415 // -----------------------------------------------------------------------------
--------- | |
416 | |
417 - (void)testReturnsValuesInPassByReferenceArguments | |
418 { | |
419 NSString *expectedName = [NSString stringWithString:@"Test"]; | |
420 NSArray *expectedArray = [NSArray array]; | |
421 | |
422 [[mock expect] completePathIntoString:[OCMArg setTo:expectedName] caseSe
nsitive:YES | |
423 matchesIntoArray:[OCMArg setTo:
expectedArray] filterTypes:OCMOCK_ANY]; | |
424 | |
425 NSString *actualName = nil; | |
426 NSArray *actualArray = nil; | |
427 [mock completePathIntoString:&actualName caseSensitive:YES matchesIntoAr
ray:&actualArray filterTypes:nil]; | |
428 | |
429 STAssertNoThrow([mock verify], @"An unexpected exception was thrown"); | |
430 STAssertEqualObjects(expectedName, actualName, @"The two string objects
should be equal"); | |
431 STAssertEqualObjects(expectedArray, actualArray, @"The two array objects
should be equal"); | |
432 } | |
433 | |
434 | |
435 // -----------------------------------------------------------------------------
--------- | |
436 // accepting expected methods | |
437 // -----------------------------------------------------------------------------
--------- | |
438 | |
439 - (void)testAcceptsExpectedMethod | |
440 { | |
441 [[mock expect] lowercaseString]; | |
442 [mock lowercaseString]; | |
443 } | |
444 | |
445 | |
446 - (void)testAcceptsExpectedMethodAndReturnsValue | |
447 { | |
448 id returnValue; | |
449 | |
450 [[[mock expect] andReturn:@"Objective-C"] lowercaseString]; | |
451 returnValue = [mock lowercaseString]; | |
452 | |
453 STAssertEqualObjects(@"Objective-C", returnValue, @"Should have returned
stubbed value."); | |
454 } | |
455 | |
456 | |
457 - (void)testAcceptsExpectedMethodsInRecordedSequence | |
458 { | |
459 [[mock expect] lowercaseString]; | |
460 [[mock expect] uppercaseString]; | |
461 | |
462 [mock lowercaseString]; | |
463 [mock uppercaseString]; | |
464 } | |
465 | |
466 | |
467 - (void)testAcceptsExpectedMethodsInDifferentSequence | |
468 { | |
469 [[mock expect] lowercaseString]; | |
470 [[mock expect] uppercaseString]; | |
471 | |
472 [mock uppercaseString]; | |
473 [mock lowercaseString]; | |
474 } | |
475 | |
476 | |
477 // -----------------------------------------------------------------------------
--------- | |
478 // verifying expected methods | |
479 // -----------------------------------------------------------------------------
--------- | |
480 | |
481 - (void)testAcceptsAndVerifiesExpectedMethods | |
482 { | |
483 [[mock expect] lowercaseString]; | |
484 [[mock expect] uppercaseString]; | |
485 | |
486 [mock lowercaseString]; | |
487 [mock uppercaseString]; | |
488 | |
489 [mock verify]; | |
490 } | |
491 | |
492 | |
493 - (void)testRaisesExceptionOnVerifyWhenNotAllExpectedMethodsWereCalled | |
494 { | |
495 [[mock expect] lowercaseString]; | |
496 [[mock expect] uppercaseString]; | |
497 | |
498 [mock lowercaseString]; | |
499 | |
500 STAssertThrows([mock verify], @"Should have raised an exception."); | |
501 } | |
502 | |
503 - (void)testAcceptsAndVerifiesTwoExpectedInvocationsOfSameMethod | |
504 { | |
505 [[mock expect] lowercaseString]; | |
506 [[mock expect] lowercaseString]; | |
507 | |
508 [mock lowercaseString]; | |
509 [mock lowercaseString]; | |
510 | |
511 [mock verify]; | |
512 } | |
513 | |
514 | |
515 - (void)testAcceptsAndVerifiesTwoExpectedInvocationsOfSameMethodAndReturnsCorres
pondingValues | |
516 { | |
517 [[[mock expect] andReturn:@"foo"] lowercaseString]; | |
518 [[[mock expect] andReturn:@"bar"] lowercaseString]; | |
519 | |
520 STAssertEqualObjects(@"foo", [mock lowercaseString], @"Should have retur
ned first stubbed value"); | |
521 STAssertEqualObjects(@"bar", [mock lowercaseString], @"Should have retur
ned seconds stubbed value"); | |
522 | |
523 [mock verify]; | |
524 } | |
525 | |
526 - (void)testReturnsStubbedValuesIndependentOfExpectations | |
527 { | |
528 [[mock stub] hasSuffix:@"foo"]; | |
529 [[mock expect] hasSuffix:@"bar"]; | |
530 | |
531 [mock hasSuffix:@"foo"]; | |
532 [mock hasSuffix:@"bar"]; | |
533 [mock hasSuffix:@"foo"]; // Since it's a stub, shouldn't matter how many
times we call this | |
534 | |
535 [mock verify]; | |
536 } | |
537 | |
538 -(void)testAcceptsAndVerifiesMethodsWithSelectorArgument | |
539 { | |
540 [[mock expect] performSelector:@selector(lowercaseString)]; | |
541 [mock performSelector:@selector(lowercaseString)]; | |
542 [mock verify]; | |
543 } | |
544 | |
545 | |
546 // -----------------------------------------------------------------------------
--------- | |
547 // ordered expectations | |
548 // -----------------------------------------------------------------------------
--------- | |
549 | |
550 - (void)testAcceptsExpectedMethodsInRecordedSequenceWhenOrderMatters | |
551 { | |
552 [mock setExpectationOrderMatters:YES]; | |
553 | |
554 [[mock expect] lowercaseString]; | |
555 [[mock expect] uppercaseString]; | |
556 | |
557 STAssertNoThrow([mock lowercaseString], @"Should have accepted expected
method in sequence."); | |
558 STAssertNoThrow([mock uppercaseString], @"Should have accepted expected
method in sequence."); | |
559 } | |
560 | |
561 - (void)testRaisesExceptionWhenSequenceIsWrongAndOrderMatters | |
562 { | |
563 [mock setExpectationOrderMatters:YES]; | |
564 | |
565 [[mock expect] lowercaseString]; | |
566 [[mock expect] uppercaseString]; | |
567 | |
568 STAssertThrows([mock uppercaseString], @"Should have complained about wr
ong sequence."); | |
569 } | |
570 | |
571 | |
572 // -----------------------------------------------------------------------------
--------- | |
573 // explicitly rejecting methods (mostly for nice mocks, see below) | |
574 // -----------------------------------------------------------------------------
--------- | |
575 | |
576 - (void)testThrowsWhenRejectedMethodIsCalledOnNiceMock | |
577 { | |
578 mock = [OCMockObject niceMockForClass:[NSString class]]; | |
579 | |
580 [[mock reject] uppercaseString]; | |
581 STAssertThrows([mock uppercaseString], @"Should have complained about re
jected method being called."); | |
582 } | |
583 | |
584 | |
585 // -----------------------------------------------------------------------------
--------- | |
586 // protocol mocks | |
587 // -----------------------------------------------------------------------------
--------- | |
588 | |
589 - (void)testCanMockFormalProtocol | |
590 { | |
591 mock = [OCMockObject mockForProtocol:@protocol(NSLocking)]; | |
592 [[mock expect] lock]; | |
593 | |
594 [mock lock]; | |
595 | |
596 [mock verify]; | |
597 } | |
598 | |
599 - (void)testRaisesWhenUnknownMethodIsCalledOnProtocol | |
600 { | |
601 mock = [OCMockObject mockForProtocol:@protocol(NSLocking)]; | |
602 STAssertThrows([mock lowercaseString], @"Should have raised an exception
."); | |
603 } | |
604 | |
605 - (void)testConformsToMockedProtocol | |
606 { | |
607 mock = [OCMockObject mockForProtocol:@protocol(NSLocking)]; | |
608 STAssertTrue([mock conformsToProtocol:@protocol(NSLocking)], nil); | |
609 } | |
610 | |
611 - (void)testRespondsToValidProtocolRequiredSelector | |
612 { | |
613 mock = [OCMockObject mockForProtocol:@protocol(TestProtocol)]; | |
614 STAssertTrue([mock respondsToSelector:@selector(primitiveValue)], nil); | |
615 } | |
616 | |
617 - (void)testRespondsToValidProtocolOptionalSelector | |
618 { | |
619 mock = [OCMockObject mockForProtocol:@protocol(TestProtocol)]; | |
620 STAssertTrue([mock respondsToSelector:@selector(objectValue)], nil); | |
621 } | |
622 | |
623 - (void)testDoesNotRespondToInvalidProtocolSelector | |
624 { | |
625 mock = [OCMockObject mockForProtocol:@protocol(TestProtocol)]; | |
626 STAssertFalse([mock respondsToSelector:@selector(fooBar)], nil); | |
627 } | |
628 | |
629 | |
630 // -----------------------------------------------------------------------------
--------- | |
631 // nice mocks don't complain about unknown methods | |
632 // -----------------------------------------------------------------------------
--------- | |
633 | |
634 - (void)testReturnsDefaultValueWhenUnknownMethodIsCalledOnNiceClassMock | |
635 { | |
636 mock = [OCMockObject niceMockForClass:[NSString class]]; | |
637 STAssertNil([mock lowercaseString], @"Should return nil on unexpected me
thod call (for nice mock)."); | |
638 [mock verify]; | |
639 } | |
640 | |
641 - (void)testRaisesAnExceptionWhenAnExpectedMethodIsNotCalledOnNiceClassMock | |
642 { | |
643 mock = [OCMockObject niceMockForClass:[NSString class]]; | |
644 [[[mock expect] andReturn:@"HELLO!"] uppercaseString]; | |
645 STAssertThrows([mock verify], @"Should have raised an exception because
method was not called."); | |
646 } | |
647 | |
648 - (void)testReturnDefaultValueWhenUnknownMethodIsCalledOnProtocolMock | |
649 { | |
650 mock = [OCMockObject niceMockForProtocol:@protocol(TestProtocol)]; | |
651 STAssertTrue(0 == [mock primitiveValue], @"Should return 0 on unexpected
method call (for nice mock)."); | |
652 [mock verify]; | |
653 } | |
654 | |
655 - (void)testRaisesAnExceptionWenAnExpectedMethodIsNotCalledOnNiceProtocolMock | |
656 { | |
657 mock = [OCMockObject niceMockForProtocol:@protocol(TestProtocol)]; | |
658 [[mock expect] primitiveValue]; | |
659 STAssertThrows([mock verify], @"Should have raised an exception because
method was not called."); | |
660 } | |
661 | |
662 | |
663 // -----------------------------------------------------------------------------
--------- | |
664 // partial mocks forward unknown methods to a real instance | |
665 // -----------------------------------------------------------------------------
--------- | |
666 | |
667 - (void)testStubsMethodsOnPartialMock | |
668 { | |
669 TestClassThatCallsSelf *foo = [[[TestClassThatCallsSelf alloc] init] aut
orelease]; | |
670 mock = [OCMockObject partialMockForObject:foo]; | |
671 [[[mock stub] andReturn:@"hi"] method1]; | |
672 STAssertEqualObjects(@"hi", [mock method1], @"Should have returned stubb
ed value"); | |
673 } | |
674 | |
675 | |
676 //- (void)testStubsMethodsOnPartialMockForTollFreeBridgedClasses | |
677 //{ | |
678 // mock = [OCMockObject partialMockForObject:[NSString stringWithString:@"h
ello"]]; | |
679 // [[[mock stub] andReturn:@"hi"] uppercaseString]; | |
680 // STAssertEqualObjects(@"hi", [mock uppercaseString], @"Should have return
ed stubbed value"); | |
681 //} | |
682 | |
683 - (void)testForwardsUnstubbedMethodsCallsToRealObjectOnPartialMock | |
684 { | |
685 TestClassThatCallsSelf *foo = [[[TestClassThatCallsSelf alloc] init] aut
orelease]; | |
686 mock = [OCMockObject partialMockForObject:foo]; | |
687 STAssertEqualObjects(@"Foo", [mock method2], @"Should have returned valu
e from real object."); | |
688 } | |
689 | |
690 //- (void)testForwardsUnstubbedMethodsCallsToRealObjectOnPartialMockForTollFreeB
ridgedClasses | |
691 //{ | |
692 // mock = [OCMockObject partialMockForObject:[NSString stringWithString:@"h
ello2"]]; | |
693 // STAssertEqualObjects(@"HELLO2", [mock uppercaseString], @"Should have re
turned value from real object."); | |
694 //} | |
695 | |
696 - (void)testStubsMethodOnRealObjectReference | |
697 { | |
698 TestClassThatCallsSelf *realObject = [[[TestClassThatCallsSelf alloc] in
it] autorelease]; | |
699 mock = [OCMockObject partialMockForObject:realObject]; | |
700 [[[mock stub] andReturn:@"TestFoo"] method1]; | |
701 STAssertEqualObjects(@"TestFoo", [realObject method1], @"Should have stu
bbed method."); | |
702 } | |
703 | |
704 - (void)testRestoresObjectWhenStopped | |
705 { | |
706 TestClassThatCallsSelf *realObject = [[[TestClassThatCallsSelf alloc] in
it] autorelease]; | |
707 mock = [OCMockObject partialMockForObject:realObject]; | |
708 [[[mock stub] andReturn:@"TestFoo"] method2]; | |
709 STAssertEqualObjects(@"TestFoo", [realObject method2], @"Should have stu
bbed method."); | |
710 [mock stop]; | |
711 STAssertEqualObjects(@"Foo", [realObject method2], @"Should have 'unstub
bed' method."); | |
712 } | |
713 | |
714 | |
715 - (void)testCallsToSelfInRealObjectAreShadowedByPartialMock | |
716 { | |
717 TestClassThatCallsSelf *foo = [[[TestClassThatCallsSelf alloc] init] aut
orelease]; | |
718 mock = [OCMockObject partialMockForObject:foo]; | |
719 [[[mock stub] andReturn:@"FooFoo"] method2]; | |
720 STAssertEqualObjects(@"FooFoo", [mock method1], @"Should have called thr
ough to stubbed method."); | |
721 } | |
722 | |
723 - (NSString *)differentMethodInDifferentClass | |
724 { | |
725 return @"swizzled!"; | |
726 } | |
727 | |
728 - (void)testImplementsMethodSwizzling | |
729 { | |
730 // using partial mocks and the indirect return value provider | |
731 TestClassThatCallsSelf *foo = [[[TestClassThatCallsSelf alloc] init] aut
orelease]; | |
732 mock = [OCMockObject partialMockForObject:foo]; | |
733 [[[mock stub] andCall:@selector(differentMethodInDifferentClass) onObjec
t:self] method1]; | |
734 STAssertEqualObjects(@"swizzled!", [foo method1], @"Should have returned
value from different method"); | |
735 } | |
736 | |
737 | |
738 - (void)aMethodWithVoidReturn | |
739 { | |
740 } | |
741 | |
742 - (void)testMethodSwizzlingWorksForVoidReturns | |
743 { | |
744 TestClassThatCallsSelf *foo = [[[TestClassThatCallsSelf alloc] init] aut
orelease]; | |
745 mock = [OCMockObject partialMockForObject:foo]; | |
746 [[[mock stub] andCall:@selector(aMethodWithVoidReturn) onObject:self] me
thod1]; | |
747 STAssertNoThrow([foo method1], @"Should have worked."); | |
748 } | |
749 | |
750 | |
751 // -----------------------------------------------------------------------------
--------- | |
752 // mocks should honour the NSObject contract, etc. | |
753 // -----------------------------------------------------------------------------
--------- | |
754 | |
755 - (void)testRespondsToValidSelector | |
756 { | |
757 STAssertTrue([mock respondsToSelector:@selector(lowercaseString)], nil); | |
758 } | |
759 | |
760 - (void)testDoesNotRespondToInvalidSelector | |
761 { | |
762 STAssertFalse([mock respondsToSelector:@selector(fooBar)], nil); | |
763 } | |
764 | |
765 - (void)testCanStubValueForKeyMethod | |
766 { | |
767 id returnValue; | |
768 | |
769 mock = [OCMockObject mockForClass:[NSObject class]]; | |
770 [[[mock stub] andReturn:@"SomeValue"] valueForKey:@"SomeKey"]; | |
771 | |
772 returnValue = [mock valueForKey:@"SomeKey"]; | |
773 | |
774 STAssertEqualObjects(@"SomeValue", returnValue, @"Should have returned v
alue that was set up."); | |
775 } | |
776 | |
777 - (void)testWorksWithTypeQualifiers | |
778 { | |
779 id myMock = [OCMockObject mockForProtocol:@protocol(ProtocolWithTypeQual
ifierMethod)]; | |
780 | |
781 STAssertNoThrow([[myMock expect] aSpecialMethod:"foo"], @"Should not com
plain about method with type qualifiers."); | |
782 STAssertNoThrow([myMock aSpecialMethod:"foo"], @"Should not complain abo
ut method with type qualifiers."); | |
783 } | |
784 | |
785 | |
786 // -----------------------------------------------------------------------------
--------- | |
787 // some internal tests | |
788 // -----------------------------------------------------------------------------
--------- | |
789 | |
790 - (void)testReRaisesFailFastExceptionsOnVerify | |
791 { | |
792 @try | |
793 { | |
794 [mock lowercaseString]; | |
795 } | |
796 @catch(NSException *exception) | |
797 { | |
798 // expected | |
799 } | |
800 STAssertThrows([mock verify], @"Should have reraised the exception."); | |
801 } | |
802 | |
803 - (void)testReRaisesRejectExceptionsOnVerify | |
804 { | |
805 mock = [OCMockObject niceMockForClass:[NSString class]]; | |
806 [[mock reject] uppercaseString]; | |
807 @try | |
808 { | |
809 [mock uppercaseString]; | |
810 } | |
811 @catch(NSException *exception) | |
812 { | |
813 // expected | |
814 } | |
815 STAssertThrows([mock verify], @"Should have reraised the exception."); | |
816 } | |
817 | |
818 | |
819 - (void)testCanCreateExpectationsAfterInvocations | |
820 { | |
821 [[mock expect] lowercaseString]; | |
822 [mock lowercaseString]; | |
823 [mock expect]; | |
824 } | |
825 | |
826 @end | |
OLD | NEW |