如何部分模拟外部对象
How to partially mock external object
我有 class 方法来测试依赖对象(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 对象和 return "MY_API_KEY" 值,但测试方法失败并且 return 是真正的 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"]);
});
});
也许这对你有用:
测试方法之外的某处:
static NSString *gMockApiKey = @"MY_API_KEY";
像这样存根方法:
OCMStub([keysPartialMock APIKey]).andDo(^(NSInvocation *invocation)
{
[invocation setReturnValue:&gMockApiKey];
});
编辑:
由于 APIRouter 可能正在使用它自己的 Keys 实例,您可以尝试 class 模拟:
id keysMock = OCMClassMock([Keys class]);
OCMStub(ClassMethod([keysMock APIKey])).andDo(^(NSInvocation *invocation)
{
[invocation setReturnValue:&gMockApiKey];
});
编辑2:
所以..我认为模拟它的正确方法是创建一个 Keys 的模拟实例。
测试文件顶部的某处:
static Keys *gMockedKeys = nil;
static NSString *gMockApiKey = @"MY_API_KEY";
设置:
- (void)setUp {
[super setUp];
gMockedKeys = [Keys new];
id keysPartialMock = OCMPartialMock(gMockedKeys);
OCMStub([keysPartialMock APIKey]).andDo(^(NSInvocation *invocation)
{
[invocation setReturnValue:&gMockApiKey];
});
}
测试:
- (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..");
}
我有 class 方法来测试依赖对象(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 对象和 return "MY_API_KEY" 值,但测试方法失败并且 return 是真正的 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"]);
});
});
也许这对你有用:
测试方法之外的某处:
static NSString *gMockApiKey = @"MY_API_KEY";
像这样存根方法:
OCMStub([keysPartialMock APIKey]).andDo(^(NSInvocation *invocation)
{
[invocation setReturnValue:&gMockApiKey];
});
编辑:
由于 APIRouter 可能正在使用它自己的 Keys 实例,您可以尝试 class 模拟:
id keysMock = OCMClassMock([Keys class]);
OCMStub(ClassMethod([keysMock APIKey])).andDo(^(NSInvocation *invocation)
{
[invocation setReturnValue:&gMockApiKey];
});
编辑2:
所以..我认为模拟它的正确方法是创建一个 Keys 的模拟实例。
测试文件顶部的某处:
static Keys *gMockedKeys = nil;
static NSString *gMockApiKey = @"MY_API_KEY";
设置:
- (void)setUp {
[super setUp];
gMockedKeys = [Keys new];
id keysPartialMock = OCMPartialMock(gMockedKeys);
OCMStub([keysPartialMock APIKey]).andDo(^(NSInvocation *invocation)
{
[invocation setReturnValue:&gMockApiKey];
});
}
测试:
- (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..");
}