OCMock:如何存根 - [NSString stringWithContentsOfURL:encoding:error:]

时间:2016-02-02 01:36:27

标签: ios objective-c ocmock

我尝试了很多东西。这仍然不起作用:

 id stringMock = OCMClassMock([NSString class]);

 [[[[stringMock stub] ignoringNonObjectArgs] stringWithContentsOfURL:[OCMArg anyPointer] encoding:NSUTF8StringEncoding error:(NSError * __autoreleasing *)[OCMArg anyPointer]] andReturn:stringFromFile];

如何在我的代码中的任何位置进行 - [NSString stringWithContentsOfURL:encoding:error:]返回stringFromFile

2 个答案:

答案 0 :(得分:2)

不幸的是,这是不可能的。

来自OCMock documentation关于限制(第10部分):

  

10.5 NSString上的类方法无法存根或验证

     

id stringMock   = OCMClassMock([NSString class]); //以下内容不起作用OCMStub([stringMock stringWithContentsOfFile:[OCMArg any]   编码:NSUTF8StringEncoding错误:[OCMArg setTo:nil]]);

     

不是   可以在NSString上存根或验证类方法。试着这样做   没有效果。

但是,您可以包装NSString并模拟包装器。这意味着您需要使用此包装替换代码中的所有调用,但测试可以正常工作..

以下是一个例子:

包装器:

@interface NSStringWrapper : NSObject
+ (nullable id)stringWithContentsOfURL:(NSURL *)url;
@end

@implementation NSStringWrapper
+ (nullable id)stringWithContentsOfURL:(NSURL *)url
{
    return [NSString stringWithContentsOfURL:url];
}
@end

测试:

static NSString *stringFromFile = @"myStringFromFile";

-(void)testStringWrapper
{
    id nsstringWrapperMock = OCMClassMock([NSStringWrapper class]);
    OCMStub(ClassMethod([nsstringWrapperMock stringWithContentsOfURL:OCMOCK_ANY])).andDo(^(NSInvocation *invocation)
    {
      [invocation setReturnValue:&stringFromFile];
    });

    NSURL *fakeURL = [NSURL URLWithString:@"htttp://google.com"];
    NSString *test = [NSStringWrapper stringWithContentsOfURL:fakeURL];
    XCTAssertEqual(test, stringFromFile, @"Should always return stringFromFile");
}

答案 1 :(得分:0)

另一个选择是尝试OCMockito,它以不同于OCMock的方式模拟类方法。

__strong Class mockStringClass = mockClass([NSString class]);
[[given([mockStringClass stringWithContentsOfFile:anything() 
                                         encoding:NSUTF8StringEncoding 
                                            error:NULL])
        withMatcher:anything() forArgument:2]
        willReturn:stringFromFile];

与调用类方法的OCMock不同,这需要您注入类。也就是说,代替生产代码直接调用

str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];

你需要做类似

的事情
str = [self.stringClass stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];

您应该能够在不中断现有OCMock使用的情况下添加OCMockito。