У меня есть класс Swift, который я тестирую на модуле. Основной целью этого класса является создание HTTP-вызовов. Я только что закончил издеваться над всеми сетевыми запросами, используя Mockingjay, но я хочу убедиться, что в будущем я не забываю издеваться над будущими запросами. В то время как я делал первоначальное издевательство, я заменил базовый URL, который я использую, с тем, который не работает, но я хотел бы оставить это на месте только для моих тестов. Класс испытываемого выглядит следующим образом:Как переопределить класс-свойство Swift для тестирования
public class MyWebServiceWrapper {
...
public class var baseURL: String {
return "https://api.thesite.com"
}
...
}
Я пытался использовать OCMock из класса Objective-C, чтобы заменить baseURL
«s реализация, и я попытался с помощью метода swizzling as described on NSHipster а (I сделал класс из NSObject
и заменил baseURL
на метод вместо указанного выше свойства - я бы предпочел не swizzle, тем более, что мне не нужен класс, который должен быть подклассом NSObject
).
Это код, который я использовал, чтобы выполнить попытку swizzle, которая не имела никакого эффекта. Для обоих покушений решений ниже, я переписал мой класс тестируемой как так (так как это выглядело, как ни один подход не будет хорошо работать с Swift свойствами или чисто Swift классов):
@objc public class MyWebServiceWrapper: NSObject {
...
public class var baseURL: String {
return baseURLValue()
}
public class func baseURLValue() -> String {
return "https://api.thesite.com"
}
...
}
Это был мой swizzling попытки (в 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
?
Вы должны найти другой путь, потому что в противном случае это обходной путь :( ли вы какие-либо решения – denis631
@ denis631 я до сих пор? используя ответ, который я привел ниже – Dov
Грустный ... Это просто не похоже на правду, но вы знаете ... GTD: ПОЛУЧИТЕ ВЕЩИ :) – denis631