Feature tests with KIF: beforeEach is called after my view controller is loaded?

主宰稳场 提交于 2019-12-11 10:43:45

问题


i have got simple (i guess) question.

I want to make a feature test in my app with Specta and KIF. The problem is that i am setting dependency in viewDidLoad method of my View Controller, and in beforeEach method of my spec i'm injecting fake object just to not hit the network.

The result is wrong because viewDidLoad is being called before beforeEach method in specs.

Is there a possibility to set dependencies before AppDelegate loads root view controller so everything is set up properly?


回答1:


Tests that depend on a target (like KIF and certain unit tests) launch after the app is launched so no, you can not make the beforeEach go before your AppDelegate without some terrible hackery.

I don't know how you're doing dependency injection so here's how we do it/some general strategies.

KIF tests should ideally not mock at the code level

This is because KIF is kind of an alternative to UIAutomation and mainly useful for feature/functional tests at the UI level. You don't really want to change your application code so much. Mocks are best achieved using frameworks like OHHTTPStubs for network or OCMock for objects and those work best when limited to unit tests.

How to mock out network requests in a "real" app

The best way here is to use something like OHHTTPStubs or AMY server (made by same people that made KIF) or Nocilla to return stub responses. This way you can let your app code run fully. OHHTTPStubs for example uses NSURLProtocol to intercept your requests so from the app perspective it's almost as good as going out to the network.

I really want to mock out those objects

If you really really really want to mock out dependency injected objects with different objects then there are a couple of more and less hacky options.

1) Use a real DI framework (or build your own) that allow for patching of the dependencies. I've used Typhoon and it's reasonable. The standard idea here is to use Inversion of Control to your advantage. Since you're getting all your objects from an application context rather than directly, it's much easier to tweak the application context abstraction layer. Typhoon even has a wiki page on this topic: https://github.com/appsquickly/Typhoon/wiki/Integration-Testing

2) Trace the source of the object you're injecting and want to mock out and change it at the source. This isn't the most elegant and you're sort of hacking out a DI framework anyway but maybe you don't have enough time or complexity to make switching to a DI framework worth it.

3) Hack all the way to the top level. Have a test AppDelegate that subclasses from your normal AppDelegate and use that during KIF testing (and of course have it stub out or mock out objects you want). This isn't flexible but again, maybe you just want one test case or something:

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;
}

Ultimately this isn't a simple "where do I put this method" question unfortunately.



来源:https://stackoverflow.com/questions/28502498/feature-tests-with-kif-beforeeach-is-called-after-my-view-controller-is-loaded

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!