我有一个简单的(我猜)问题。
我想在我的应用程序中使用Specta和KIF进行功能测试。问题是我在我的View Controller的viewDidLoad方法中设置依赖项,并且在我的规范的beforeEach方法中我注入假对象只是为了不打网络。
结果是错误的,因为在规范中的beforeEach方法之前调用了viewDidLoad。
是否有可能在AppDelegate加载根视图控制器之前设置依赖关系,以便正确设置所有内容?
答案 0 :(得分:5)
依赖于目标(如KIF和某些单元测试)的测试在应用程序启动后启动,所以不,你不能让beforeEach在你的AppDelegate之前没有一些可怕的hackery。
我不知道你是如何进行依赖注入的,所以我们这样做是怎么做的/一些一般策略。
理想情况下,KIF测试不应在代码级别进行模拟
这是因为KIF是UIAutomation的替代品,主要用于UI级别的功能/功能测试。您并不是真的想要更改应用程序代码。模拟最好使用OHHTTPStubs等框架用于网络或OCMock用于对象,并且仅限于单元测试时效果最佳。
如何在"真实"中模拟网络请求?应用
这里最好的方法是使用像OHHTTPStubs或AMY服务器(由制作KIF的同一个人制作)或Nocilla来返回存根响应。这样您就可以让您的应用代码完全运行。例如,OHHTTPStubs使用NSURLProtocol拦截您的请求,因此从应用程序的角度来看,它几乎和外出网络一样好。
我真的想嘲笑那些对象
如果你真的真的想要用不同的对象模拟依赖注入的对象,那么有一些或多或少的hacky选项。
1)使用真正的DI框架(或构建自己的框架),允许修补依赖项。我使用了台风,这是合理的。这里的标准想法是使用控制反转对您有利。由于您从应用程序上下文而不是直接获取所有对象,因此调整应用程序上下文抽象层要容易得多。 Typhoon甚至还有关于此话题的维基页面:https://github.com/appsquickly/Typhoon/wiki/Integration-Testing
2)跟踪您注入的对象的来源,并希望在源处模拟并更改它。这并不是最优雅的,你无论如何都会破解DI框架,但也许你没有足够的时间或复杂性来转换到符合它的DI框架。
3)哈克一直到顶级。让测试AppDelegate从您的普通AppDelegate中进行子类化并在KIF测试期间使用它(当然还有它存根或模拟出你想要的对象)。这不灵活,但是,您可能只需要一个测试用例或其他内容:
int main(int argc, char *argv[])
{
int returnValue;
@autoreleasepool {
BOOL inIntegrationTests = NSClassFromString(@"KIFTestCase") != nil;
if (inIntegrationTests) {
returnValue = UIApplicationMain(argc, argv, nil, @"AppDelegateForTest");
}
else {
returnValue = UIApplicationMain(argc, argv, nil, @"AppDelegate");
}
}
return returnValue;
}
最终这不是一个简单的"我在哪里放这个方法"不幸的是。