2

我有以下失败的单元测试。我认为这是因为OCMock在多个线程中不能很好地工作,但我可能是错的。mockTestMethodA永远不会被调用。如果我修改代码以testMethodA在同一线程上调用 (不带NSThread),则存根似乎可以工作。这是一个已知的限制OCMock还是我错过了什么?

示例代码:

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

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

   [testClassC threadedRequestToCallMethodA];

   [self waitForCompletion:5.0];

   [mockTestClassA verify];
}

threadedRequestToCallMethodAcallMethodAFromTestClassCinTestClassC定义如下:

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

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

testMethodAinTestClassA定义为:

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

存根方法定义如下:

- (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;
 }

感谢您的帮助。

谢谢。

4

1 回答 1

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
于 2013-04-19T16:26:30.900 回答