如何部分模拟外部对象

我有类方法来testing依赖对象(Keys对象)

APIRouter.m

+ (NSURL*)apiURLWithPath:(NSString*)path { MyKeys *keys = [MyKeys new]; NSString *url = [NSString stringWithFormat:@"%@?api_key=%@", path, [keys APIKey]]; return [NSURL URLWithString:url]; } 

我试图部分模拟这个Keys对象并返回“MY_API_KEY”值,但testing方法失败并返回真实的API密钥(例如as78d687as6d7das8da)。

APIRouterSpec.m

 describe(@"APIRouter", ^{ it(@"should return url for api", ^{ Keys *keys = [Keys new]; id keysPartialMock = OCMPartialMock(keys); OCMStub([keysPartialMock APIKey]).andReturn(@"MY_API_KEY"); NSURL *url = [APIRouter apiURLWithPath:@"http://www.api.com/v1/events"]; expect([url absoluteString]).to.equal([NSString stringWithFormat:@"http://www.api.com/v1/events?api_key=MY_API_KEY"]); }); }); 

也许这会为你工作:

testing方法之外的某处:

 static NSString *gMockApiKey = @"MY_API_KEY"; 

存根这样的方法:

 OCMStub([keysPartialMock APIKey]).andDo(^(NSInvocation *invocation) { [invocation setReturnValue:&gMockApiKey]; }); 

编辑:

由于APIRouter可能使用自己的Keys实例,所以可以尝试类模拟:

 id keysMock = OCMClassMock([Keys class]); OCMStub(ClassMethod([keysMock APIKey])).andDo(^(NSInvocation *invocation) { [invocation setReturnValue:&gMockApiKey]; }); 

EDIT2:

所以..我想嘲笑它的正确方法是创build一个Keys的模拟实例。

testing文件顶部的某处:

 static Keys *gMockedKeys = nil; static NSString *gMockApiKey = @"MY_API_KEY"; 

build立:

 - (void)setUp { [super setUp]; gMockedKeys = [Keys new]; id keysPartialMock = OCMPartialMock(gMockedKeys); OCMStub([keysPartialMock APIKey]).andDo(^(NSInvocation *invocation) { [invocation setReturnValue:&gMockApiKey]; }); } 

testing:

 - (void)testAPIURLWithPath { id keysMock = OCMClassMock([Keys class]); OCMStub([keysMock new]).andReturn(gMockedKeys); NSURL *url = [APIRouter apiURLWithPath:@"http://www.api.com/v1/events"]; NSString *expectedUrlString = [url absoluteString]; XCTAssertEqualObjects(expectedUrlString, @"http://www.api.com/v1/events?api_key=MY_API_KEY", @"It Should work now.."); }