1

我有简单的(我猜)问题。

我想用 Specta 和 KIF 在我的应用程序中进行功能测试。问题是我在 View Controller 的 viewDidLoad 方法中设置依赖关系,而在我的规范的 beforeEach 方法中,我正在注入假对象只是为了不访问网络。

结果是错误的,因为 viewDidLoad 在规范中的 beforeEach 方法之前被调用。

是否有可能在 AppDelegate 加载根视图控制器之前设置依赖项,以便正确设置所有内容?

4

1 回答 1

5

依赖于目标的测试(如 KIF 和某些单元测试)在应用程序启动后启动,所以不,如果没有一些可怕的骇客,你不能让 beforeEach 在你的 AppDelegate 之前运行。

我不知道您是如何进行依赖注入的,所以这是我们的做法/一些通用策略。

理想情况下,KIF 测试不应在代码级别模拟

这是因为 KIF 是 UIAutomation 的一种替代方案,主要用于 UI 级别的特性/功能测试。您并不想过多地更改您的应用程序代码。Mocks 最好使用 OHHTTPStubs 等框架来实现网络或 OCMock 用于对象,并且在仅限于单元测试时效果最好。

如何在“真实”应用中模拟网络请求

这里最好的方法是使用 OHHTTPStubs 或 AMY 服务器(由制作 KIF 的同一个人制作)或 Nocilla 之类的东西来返回存根响应。这样您就可以让您的应用程序代码完全运行。例如,OHHTTPStubs 使用 NSURLProtocol 来拦截您的请求,因此从应用程序的角度来看,它几乎与访问网络一样好。

我真的很想模拟出那些对象

如果你真的真的很想用不同的对象来模拟依赖注入的对象,那么有几个越来越少的 hacky 选项。

1) 使用允许修补依赖项的真正 DI 框架(或构建您自己的)。我用过Typhoon,它是合理的。这里的标准想法是利用控制反转来发挥您的优势。由于您从应用程序上下文而不是直接获取所有对象,因此调整应用程序上下文抽象层要容易得多。Typhoon 甚至有一个关于这个主题的 wiki 页面: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;
}

不幸的是,最终这不是一个简单的“我该把这个方法放在哪里”的问题。

于 2015-02-17T01:30:37.647 回答