问题描述
我有一种方法想与OCMock一起测试,但不确定如何执行.我要嘲笑ExtClass
未被定义为我的代码的一部分(外部库):
+(NSString *)foo:(NSString *)param
{
ExtClass *ext = [[ExtClass alloc] initWithParam:param];
if ([ext someMethod])
return @"A";
else
return @"B";
}
提前谢谢!
OCMock 2
id mock = [OCMockObject mockForClass:[ExtClass class]];
// We stub someMethod
BOOL returnedValue = YES;
[[[mock stub] andReturnValue:OCMOCK_VALUE(returnedValue)] someMethod];
// Here we stub the alloc class method **
[[[mock stub] andReturn:mock] alloc];
// And we stub initWithParam: passing the param we will pass to the method to test
NSString *param = @"someParam";
[[[mock stub] andReturn:mock] initWithParam:param];
// Here we call the method to test and we would do an assertion of its returned value...
[YourClassToTest foo:param];
OCMock3
// Parameter
NSURL *url = [NSURL URLWithString:@"http://testURL.com"];
// Set up the class to mock `alloc` and `init...`
id mockController = OCMClassMock([WebAuthViewController class]);
OCMStub([mockController alloc]).andReturn(mockController);
OCMStub([mockController initWithAuthenticationToken:OCMOCK_ANY authConfig:OCMOCK_ANY]).andReturn(mockController);
// Expect the method that needs to be called correctly
OCMExpect([mockController handleAuthResponseWithURL:url]);
// Call the method which does the work
[self.myClassInstance authStarted];
OCMVerifyAll(mockController);
注释
确保在两种情况下都存根两个方法(alloc
和init...
方法).另外,请确保两个存根调用都是在类模拟的实例上进行的(而不是类本身).
文档: OCMock功能
类方法部分>替代项
这个(奇怪的)解决方案可能在您要测试由于某种原因而无法重构的遗留代码的情况下很有用.但是,如果可以修改代码,则应该对其进行重构,并获得一个ExtClass
对象作为参数而不是一个字符串,从而从该方法中委派了ExtClass
的创建.您的生产和测试代码将更加简单明了,尤其是在更复杂的现实生活中,而不是在这个简单示例中.
I have a method I would like to test with OCMock but not sure how to do that. I need to mock ExtClass
which isn't defined as part of my code (external library):
+(NSString *)foo:(NSString *)param
{
ExtClass *ext = [[ExtClass alloc] initWithParam:param];
if ([ext someMethod])
return @"A";
else
return @"B";
}
Thanks in advance!
OCMock 2
id mock = [OCMockObject mockForClass:[ExtClass class]];
// We stub someMethod
BOOL returnedValue = YES;
[[[mock stub] andReturnValue:OCMOCK_VALUE(returnedValue)] someMethod];
// Here we stub the alloc class method **
[[[mock stub] andReturn:mock] alloc];
// And we stub initWithParam: passing the param we will pass to the method to test
NSString *param = @"someParam";
[[[mock stub] andReturn:mock] initWithParam:param];
// Here we call the method to test and we would do an assertion of its returned value...
[YourClassToTest foo:param];
OCMock3
// Parameter
NSURL *url = [NSURL URLWithString:@"http://testURL.com"];
// Set up the class to mock `alloc` and `init...`
id mockController = OCMClassMock([WebAuthViewController class]);
OCMStub([mockController alloc]).andReturn(mockController);
OCMStub([mockController initWithAuthenticationToken:OCMOCK_ANY authConfig:OCMOCK_ANY]).andReturn(mockController);
// Expect the method that needs to be called correctly
OCMExpect([mockController handleAuthResponseWithURL:url]);
// Call the method which does the work
[self.myClassInstance authStarted];
OCMVerifyAll(mockController);
Notes
Ensure that in both cases you stub two methods (alloc
and the init...
method). Also, make sure that both stubbing calls are made on the instance of the class mock (not the class itself).
Docs: Class methods section in the OCMock features
Alternatives
This (strange)solution may be useful in case you want to test legacy code that due to whatever reason you cannot refactor. However, if you can modify the code you should refactor it and get an ExtClass
object as a parameter, not a string, delegating the creation of ExtClass
out of that method. Your production and test code would be simpler and clearer, specially in a more complex real life case, not in this simple example.
这篇关于如何使用未作为参数传递给方法的OCMock模拟对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!