2013-03-12 33 views
2

我有以下單元測試失敗。我認爲它是因爲OCMock在多個線程中不起作用,但我可能是錯的。 mockTestMethodA永遠不會被調用。如果我修改了代碼以在同一線程(不含NSThread)上調用testMethodA,則存根似乎工作。這是一個已知的限制OCMock還是我錯過了什麼?如何在使用OCMock的不同線程上正確存根方法?

樣品的編號:

- (void) testCallMethodUsingNSThreadFromADifferentClass 
{ 
    mockTestClassA = [OCMockObject partialMockForObject:testClassA]; 

    [[[mockTestClassA expect] andCall:@selector(mockTestMethodA) onObject:self] testMethodA]; 

    [testClassC threadedRequestToCallMethodA]; 

    [self waitForCompletion:5.0]; 

    [mockTestClassA verify]; 
} 

threadedRequestToCallMethodATestClassCcallMethodAFromTestClassC定義如下:

- (void) threadedRequestToCallMethodA 
{ 
    [NSThread detachNewThreadSelector:@selector(callMethodAFromTestClassC) toTarget:self withObject:nil]; 
} 

- (void) callMethodAFromTestClassC 
{ 
    [[[TestClassA alloc] init] testMethodA]; 
} 

testMethodATestClassA定義爲:

- (void) testMethodA 
{ 
    NSLog(@"testMethodA"); 
} 

存根方法被定義爲FOLL OWS:

- (void) mockTestMethodA 
{ 
    NSLog(@"mockTestMethodA"); 
} 

最後waitForCompletion

- (BOOL) waitForCompletion:(NSTimeInterval)timeoutSecs 
{ 
    NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeoutSecs]; 
    do { 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:timeoutDate]; 
     if([timeoutDate timeIntervalSinceNow] < 0.0) 
     break; 
    } while (!done); 

    return done; 
} 

您的幫助表示讚賞。

謝謝。

回答

0

你的問題是,你不是在你部分嘲笑的對象上調用測試方法,而是在你的callMethodAFromTestClassC中分配一個新對象。如果你在適當的對象上調用它,它可以正常工作。見下面(注意我實際上沒有創建一個單獨的類C,但效果是相同的)。作爲一個方面說明,我認爲塊和GCD使生活更容易,但每個人都有自己的風格。

// 
// TestClassTest.m 
// TestApp 
// 
// Created by Benjamin Flynn on 11/20/12. 
// 

#import <SenTestingKit/SenTestingKit.h> 
#import "OCMock.h" 
#import "TestClassA.h" 

@interface TestClassTest : SenTestCase 

@property (nonatomic, retain) TestClassA *testClassA; 
@property (atomic, assign) BOOL done; 
@end 


@implementation TestClassTest 

- (void) testCallMethodUsingNSThreadFromADifferentClass 
{ 
    self.testClassA = [[TestClassA alloc] init]; 
    id mockTestClassA = [OCMockObject partialMockForObject:self.testClassA]; 
    [[[mockTestClassA expect] andCall:@selector(mockTestMethodA) onObject:self] testMethodA]; 
    [self threadedRequestToCallMethodA]; 
    [self waitForCompletion:5.0];  
    [mockTestClassA verify]; 
} 

- (void)threadedRequestToCallMethodA 
{ 
    [NSThread detachNewThreadSelector:@selector(callMethodAFromTestClassC) toTarget:self withObject:nil]; 
} 


- (void)callMethodAFromTestClassC 
{ 
    [self.testClassA testMethodA]; 
} 

- (void)mockTestMethodA 
{ 
    NSLog(@"Mock test method A"); 
    self.done = YES; 
} 

- (BOOL)waitForCompletion:(NSTimeInterval)timeoutSecs 
{ 
    NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeoutSecs]; 
    NSLog(@"Starting timer"); 
    do { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:timeoutDate]; 
     if([timeoutDate timeIntervalSinceNow] < 0.0) 
      break; 
    } while (!self.done); 
    NSLog(@"Ending timer"); 

    return self.done; 
} 

@end 
+0

感謝您的幫助。 – 2013-04-23 21:22:44

相關問題