我有一个方法:
-(void)startTaskForResult:(long long*)result {
...
}
我要单元测试的函数调用上面的函数:
-(void)doWork {
long long result = 0;
[self startTaskForResult:&result];
}
我正在使用OCMock库进行单元测试。在我的测试用例中,我想将result
参数设置为模拟值,例如100不关心-(void)startTaskForResult:(long long*)result
的实际实施。
我尝试了以下方式:
-(void)testDoWork{
// try to set 100 to argument 'result'
OCMStub([classToTest startTaskForResult:[OCMArg setToValue:OCMOCK_VALUE((long long){100})]]);
// run the function, but it doesn't use mocked value 100 for argument 'result'
[classToTest doWork];
...
}
但是,当我运行测试时,它不会将参数result
的模拟值100使用。在我的情况下,将模拟值设置为参数的正确方法是什么?
答案 0 :(得分:2)
很少有人回答你的问题:
问题代码:
- (void)testDoWork
{
id mock = OCMPartialMock(classToTest)
OCMStub([mock startTaskForResult:[OCMArg setToValue:OCMOCK_VALUE((long long){100})]]).andForwardToRealObject;
// set your expectation here
[classToTest doWork];
}
解决您的特定问题:
startTaskForResult:
)但是,您遇到问题是因为您使用错误的方法进行测试;
编写单元测试有三种最常见的策略:
所以:
startTaskForResult:
返回特定值 - 你应该只调用它并期望返回值(不是你的情况,方法返回类型是无效的)doWork
会产生调用startTaskForResult:
的副作用,那么你应该将其存根并期待它的调用,就像我用上面的代码编写的那样。然而(!!!),但你不应该期待这样的事情。这不是一种有很多测试意义的行为,因为它是内部类的实现细节。一种可能的情况是,当两种方法都是公开的并且在类合同中明确说明时,一种方法应该通过一些初步设置来调用另一种方法。在这种情况下,您希望使用某些状态/参数进行方法调用。要使您的应用程序代码可测试,您需要不断重构代码。有些代码是不可测试的,采用应用程序代码可能更好,而不是尝试用测试覆盖它。你失去了最初的测试目标 - 重构安全性和降低成本。