如何用OCMock模拟一个没有作为参数传递给方法的对象?

sog*_*guy 7 unit-testing objective-c ocmock

我有一个方法我想用OCMock测试,但不知道如何做到这一点.我需要模拟 ExtClass哪些未定义为我的代码(外部库)的一部分:

+(NSString *)foo:(NSString *)param
{
    ExtClass *ext = [[ExtClass alloc] initWithParam:param];
    if ([ext someMethod])
        return @"A";
    else
        return @"B";
}
Run Code Online (Sandbox Code Playgroud)

提前致谢!

e19*_*985 23

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];
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

笔记

确保在两种情况下都存根两个方法(alloc和init...方法).另外,确保两个存根调用都是在类mock 的实例上进行的(而不是类本身).

Docs:OCMock功能中的类方法部分

备择方案

如果您想测试由于无法重构的原因导致的遗留代码,这个(奇怪的)解决方案可能会很有用.但是,如果您可以修改代码,则应该重构它并将ExtClass对象作为参数而不是字符串,委托创建ExtClass该方法.您的生产和测试代码将更简单,更清晰,特别是在更复杂的现实生活中,而不是在这个简单的示例中.