如何在objective-C中使用OCMock的mock和verify方法?
我的问题是我收到错误:
OCMckObject[NSNumberFormatter]: 预期的方法不是 调用:setAllowsFloats:YES
我编写了以下代码:
(void) testReturnStringFromNumber
{
id mockFormatter = [OCMockObject mockForClass:[NSNumberFormatter class]];
StringNumber *testObject = [[StringNumber alloc] init];
[[mockFormatter expect] setAllowsFloats:YES];
[testObject returnStringFromNumber:80.23456];
[mockFormatter verify];
}
@implementation StringNumber
- (NSString *) returnStringFromNumber:(float)num
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setAllowsFloats:YES];
NSString *str= [formatter stringFromNumber:[NSNumber numberWithFloat:num]];
[formatter release];
return str;
}
@end
My problem is I am getting an error:
OCMckObject[NSNumberFormatter]:
expected method was not
invoked:setAllowsFloats:YES
I have written the following code:
(void) testReturnStringFromNumber
{
id mockFormatter = [OCMockObject mockForClass:[NSNumberFormatter class]];
StringNumber *testObject = [[StringNumber alloc] init];
[[mockFormatter expect] setAllowsFloats:YES];
[testObject returnStringFromNumber:80.23456];
[mockFormatter verify];
}
@implementation StringNumber
- (NSString *) returnStringFromNumber:(float)num
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setAllowsFloats:YES];
NSString *str= [formatter stringFromNumber:[NSNumber numberWithFloat:num]];
[formatter release];
return str;
}
@end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
因为您的
StringNumber
实现使用其自己的NSNumberFormatter
对象,而不是您在测试用例中创建的对象。您需要执行一个称为“依赖反转”的经典重构操作,其中您的 StringNumber 对象将其格式化程序作为参数或 ivar,而不是在内部创建它。然后您可以将模拟格式化程序传递给它作为测试的一部分。Because your
StringNumber
implementation uses its ownNSNumberFormatter
object, not the one you created in your test case. You need to perform a classic refactoring operation called "dependency inversion", where yourStringNumber
object takes its formatter as a parameter or ivar instead of creating it internally. Then you can pass your mock formatter to it as part of your test.对于您提供的代码示例,我不担心模拟 NSNumberFormatter。您正在尝试验证
[StringNumber returnStringFromNumber:]
是否返回适当的字符串。在这种情况下,您的测试不应该关心它使用什么方法来计算该字符串,而只关心您的方法按预期工作。由于您只是返回
numberWithFloat:
返回的值,并且 NSNumberFormatter 是一个实用程序类,因此您不应该模拟它。然后,如果numberWithFloat:
的行为将来发生变化,您的测试将失败,您可以决定是否更改测试或更改您的实现。如果你模拟 NSNumberFormatter,你基本上只是测试你的方法将返回它返回的任何,所以如果它的行为改变,你的类的行为也会改变,而你不会知道它(在测试时)。
我倾向于使用模拟来:
For the code sample you present, I wouldn't worry about mocking NSNumberFormatter. You're trying to verify that
[StringNumber returnStringFromNumber:]
returns an appropriate string. Your test shouldn't care in this case what method it uses to calculate that string, just that your method works as intended.Since you just return the value returned by
numberWithFloat:
, and NSNumberFormatter is a utility class, you shouldn't mock it. Then if the behavior ofnumberWithFloat:
changes in the future, your test will fail and you can decide whether to change the test or change your implementation.If you mock NSNumberFormatter, you're basically just testing that your method will return whatever it returns, so if its behavior changes, the behavior of your class will change too, an you won't know it (at test time).
I tend to use mocks to:
您可以尝试动态重写 NSNumberFormatter 的 init 方法以返回您的模拟对象。在你的测试中,你必须从 idmockFormatter 创建一个 ivar。所以你的测试方法变成:
然后你必须为 NSNumberFormatter 类添加一个类别
因此,当你的测试代码中调用 NSNumberFormatter 的 init 方法时,如果你设置了它,将会使用一个模拟对象。
资料来源:
- http://cocoawithlove.com/2009/12/sample -mac-application-with-complete.html
问候,
昆汀
You can try to dynamically override init method of NSNumberFormatter in order to return your mock object. In your tests you have to make an ivar from id mockFormatter. So your test method becomes:
Then you have to add a category for NSNumberFormatter class
So when init method of NSNumberFormatter will be called in your code under test, a mock object will be used if you have set it.
Sources:
- http://cocoawithlove.com/2009/12/sample-mac-application-with-complete.html
Regards,
Quentin
另一个想法:
您可以尝试在 StringNumber 类中使用格式化程序创建 ivar。
然后,就可以使用测试中的键值编码来设置格式化程序值。
问候,
昆汀
Another idea:
You can try to make an ivar with formatter in StringNumber class.
Then, it will be possible to set formatter value using Key Value Coding from your tests.
Regards,
Quentin