我有一个Swift类需要进行单元测试。该类的主要目的是发起HTTP调用。我刚刚使用Mockingjay模拟了所有网络请求,但我希望确保未来的请求也能被模拟。在进行最初的模拟时,我将正在使用的基本URL替换为一个不起作用的URL,但我只想在测试中保留它。被测试的类看起来像这样:
我尝试过在Objective-C类中使用OCMock来替换
这是我用于执行尝试交换的代码,但没有任何效果。对于下面的两个尝试解决方案,我像下面这样重写了我的测试类(因为看起来两种方法都不能很好地与Swift属性或纯Swift类一起使用):
这是我的交换尝试(使用Swift)。根据日志,在每次情况下,我都会触发
public class MyWebServiceWrapper {
...
public class var baseURL: String {
return "https://api.thesite.com"
}
...
}
我尝试过在Objective-C类中使用OCMock来替换
baseURL
的实现,也尝试过使用方法交换NSHipster上描述的(我让该类从NSObject
派生并用方法替换了上面显示的属性而不是使用属性 - 我宁愿不进行方法交换,特别是因为我不需要该类成为NSObject
子类)。这是我用于执行尝试交换的代码,但没有任何效果。对于下面的两个尝试解决方案,我像下面这样重写了我的测试类(因为看起来两种方法都不能很好地与Swift属性或纯Swift类一起使用):
@objc public class MyWebServiceWrapper: NSObject {
...
public class var baseURL: String {
return baseURLValue()
}
public class func baseURLValue() -> String {
return "https://api.thesite.com"
}
...
}
这是我的交换尝试(使用Swift)。根据日志,在每次情况下,我都会触发
else
语句,以帮助弄清楚发生了什么。extension MyWebServiceWrapper {
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
if self !== MyWebServiceWrapper.self {
return
}
dispatch_once(&Static.token) {
NSLog("Replacing MyWebServiceWrapper base URL...")
let originalSelector = #selector(baseURLValue)
let swizzledSelector = #selector(networkFreeBaseURL)
guard let klass = object_getClass(self) else {
return
}
let originalMethod = class_getClassMethod(klass, originalSelector)
let swizzledMethod = class_getClassMethod(klass, swizzledSelector)
let didAddMethod = class_addMethod(klass, originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod))
if didAddMethod {
NSLog("MyWebServiceWrapper method added")
class_replaceMethod(klass, swizzledSelector, method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
NSLog("MyWebServiceWrapper implementation replaced")
}
}
}
class func networkFreeBaseURL() -> String {
return "https://tests-shouldnt-hit-the-network.com"
}
}
这是我尝试使用OCMock(在Objective-C中)替换方法的方式。该代码在配置我的单元测试期间调用。
id wrapperMock = OCMClassMock([MyWebServiceWrapper class]);
OCMStub(ClassMethod([wrapperMock baseURLValue])).andReturn(@"https://tests-shouldnt-hit-the-network.com");
如何正确实现我的目标,即从baseURL
返回无效值?