Objective c 如何使用OCMock在不同的线程上正确地存根方法?
下面的单元测试失败了。我认为这是因为,Objective c 如何使用OCMock在不同的线程上正确地存根方法?,objective-c,unit-testing,ocmock,Objective C,Unit Testing,Ocmock,下面的单元测试失败了。我认为这是因为,OCMock在多个线程中不能很好地工作,但我可能错了mockTestMethodA永远不会被调用。如果我修改代码,在同一个线程上调用testMethodA(没有NSThread),存根似乎可以工作。这是OCMock的已知限制还是我遗漏了什么 示例代码: - (void) testCallMethodUsingNSThreadFromADifferentClass { mockTestClassA = [OCMockObject partialMockF
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];
}
TestClassC
中的threadedRequestToCallMethodA
和callMethodAFromTestClassC
定义如下:
- (void) threadedRequestToCallMethodA
{
[NSThread detachNewThreadSelector:@selector(callMethodAFromTestClassC) toTarget:self withObject:nil];
}
- (void) callMethodAFromTestClassC
{
[[[TestClassA alloc] init] testMethodA];
}
- (void) mockTestMethodA
{
NSLog(@"mockTestMethodA");
}
TestClassA
中的testMethodA
定义为:
- (void) testMethodA
{
NSLog(@"testMethodA");
}
存根方法定义如下:
- (void) threadedRequestToCallMethodA
{
[NSThread detachNewThreadSelector:@selector(callMethodAFromTestClassC) toTarget:self withObject:nil];
}
- (void) callMethodAFromTestClassC
{
[[[TestClassA alloc] init] 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;
}
-(BOOL)等待完成:(NSTimeInterval)超时秒
{
NSDate*timeoutDate=[NSDate DATE WITH TIMEINTERVALICENCENOW:TIMEOUTECS];
做{
[[NSRunLoop currentRunLoop]运行模式:NSDefaultRunLoopMode beforeDate:timeoutDate];
如果([timeoutDate TimeIntervalenceNow]<0.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
//
//TestClassTest.m
//特斯塔普
//
//本杰明·弗林于2012年11月20日创作。
//
#进口
#导入“OCMock.h”
#导入“TestClassA.h”
@接口TestClassTest:SenTestCase
@属性(非原子,保留)TestClassA*TestClassA;
@属性(原子、赋值)BOOL done;
@结束
@实现TestClassTest
-(void)testCallMethodUsingNSThreadFromADifferentClass
{
self.testClassA=[[testClassA alloc]init];
id mockTestClassA=[OCMockObject partialMockForObject:self.testClassA];
[[[mockTestClassA expect]和call:@selector(mockTestMethodA)onObject:self]testMethodA];
[自线程请求调用方法A];
[自我等待完成:5.0];
[mockTestClassA验证];
}
-(无效)ThreadedRequestToCall方法A
{
[NSThread detachNewThreadSelector:@selector(callMethodAFromTestClassC)toTarget:self with Object:nil];
}
-(无效)callMethodAFromTestClassC
{
[self.testClassA testMethodA];
}
-(void)mockTestMethodA
{
NSLog(“模拟试验方法A”);
self.done=是;
}
-(BOOL)等待完成:(NSTimeInterval)超时秒
{
NSDate*timeoutDate=[NSDate DATE WITH TIMEINTERVALICENCENOW:TIMEOUTECS];
NSLog(“启动计时器”);
做{
[[NSRunLoop currentRunLoop]运行模式:NSDefaultRunLoopMode beforeDate:timeoutDate];
如果([timeoutDate TimeIntervalenceNow]<0.0)
打破
}而(!self.done);
NSLog(“结束计时器”);
返回自我完成;
}
@结束