How to partially mock external object

大兔子大兔子 提交于 2020-01-06 19:25:49

问题


I have class method to test with dependant object (Keys object)

APIRouter.m

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

I am trying to partially mock this Keys object and return "MY_API_KEY" value but the test method fails and returns real API key (e.g. 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"]);
    });
});

回答1:


Maybe this will work for you:

Somewhere outside your test method:

static NSString *gMockApiKey = @"MY_API_KEY";

Stub the method like this:

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

Edit:

Since APIRouter is probably using its own instance of Keys you can try a class mock:

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

Edit2:

So.. I think the proper way to mock it would be to create a mock instance of Keys.

Somewhere at the top of your test file:

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

setUp:

- (void)setUp {

    [super setUp];

    gMockedKeys = [Keys new];

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

test:

- (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..");
}


来源:https://stackoverflow.com/questions/30608038/how-to-partially-mock-external-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!