iOS单元测试如何阻止App Delegate做事

Posted

技术标签:

【中文标题】iOS单元测试如何阻止App Delegate做事【英文标题】:iOS Unit Testing how to stop App Delegate from doing stuff 【发布时间】:2014-01-20 21:19:40 【问题描述】:

我有一个正在单元测试的应用。在正常使用情况下,App Delegate 进行设置,并开始运行。但是,当我运行单元测试时,我希望 App Delegate 不做太多事情,如果有的话。我将如何实现这一目标?似乎一些设置的东西在测试运行器运行时正在运行,并且它往往会在测试运行时抛出异常,导致它失败。

【问题讨论】:

这个答案可以帮助[Xcode项目如何以编程方式检测目标或如何使用环境变量] (***.com/a/6964951/310903) Unit Testing in Xcode, does it run the app? 的可能重复项您会在那里找到答案。 【参考方案1】:

您想研究 Mocks(或双打)。一般来说,这是在进行测试以绕过服务器调用、打印、日志记录等事情时转移调用的一种方式......

在最简单的形式中,您只需将要为测试修改的对象子类化即可。

说你有

@interface YourClass : NSObject
    @property NSString *dataFromServer;
@end

@implementation YourClass

-(void) load

    // Bunch of calls to the server you don't want to do while testing.
    self.dataFromServer = dataFromServerCallsYouDontWantToRun;


-(NSString*) getServerData

    return dataFromServer;


@end

假设您想测试 getServerData,但不想因为调用数据库而实际运行负载。假设您只想将 dataFromServer 硬编码为 @"Mock"。

在您的 UnitTest 项目中,从 YourClass 继承并覆盖您不想在测试中实际运行的任何函数。

@interface YourClassMock : YourClass

@end

@implementation YourClassMock

-(void) load

    NSLog(@"In Mock");
    self.dataFromServer = @"Mock";


@end

现在你的测试看起来像这样

- (void) testLoad

    YourClassMock yourClass = [[YourClassMock alloc] init];
    [yourClass load];
    STAssertEquals([yourClass getServerData], @"Mock", @"Returns mock data");

因此,您无需实际调用复杂的加载方法即可全面测试 getServerData。

这是一个基本的,自己动手做的例子,但是有很多库可以帮助加快这个速度,比如 OCMock (http://ocmock.org/)。这可以为您创建模拟对象,而无需子类。你应该调查一下。但希望您了解如何使用它。更多信息 - http://nshipster.com/unit-testing/

【讨论】:

我喜欢你关于模拟的信息,但在 OPs 的情况下,由于应用程序启动与测试的竞争条件,这将如何工作?我的意思是,XCTestCase 是否在应用程序启动生命周期中的某个时间点执行,这是可预测的,以便您可以模拟应用程序委托的启动功能? XCTest 是它自己的目标。它运行而不是应用程序来运行您的部分代码。理想情况下,一次只对一小部分进行单元测试。当您运行测试时,您并没有直接运行您的应用程序。 NSHipster 链接很好地解释了它。

以上是关于iOS单元测试如何阻止App Delegate做事的主要内容,如果未能解决你的问题,请参考以下文章

如何从 UI 测试访问 App Delegate?

iOS 如何告诉 App Delegate 从当前视图呈现新视图

模拟课程 - iOS

如何阻止 UITableView 在 iOS 7 中剪辑 UITableViewCell 内容

QuickBlox iOS SDK,启用云后端服务器 AUTHKEY/APPLICATION ID TO APP DELEGATE

涉及 NSDocumentDirectory 和其他 iOS App 特定调用的静态库的单元测试