iOS-单元测试异步代码 [英] iOS - Unit Testing Asynchoronous code

查看:235
本文介绍了iOS-单元测试异步代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要测试的方法的一部分如下:

The part of a method that I am trying to test is as follows:

- (void)configureTableFooterView {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.tableView.tableFooterView = nil;

        if ([self.parser.resultSet isLastPage]) {
            return;
        }
    });
}

我编写了如下单元测试:

I have written the unit test as follows:

- (void)testTableFooterViewConfigurationAfterLastPageLoaded {

    id mockTableView = OCMClassMock([GMGFlatTableView class]);

    OCMExpect([mockTableView setTableFooterView:[OCMArg isNil]]);

    id resultSet = OCMClassMock([GMGResultSetInfo class]);

    OCMStub([resultSet isLastPage]).andReturn(YES);

    OCMStub([self.mockParser resultSet]).andReturn(resultSet);

    id partialMockSUT = OCMPartialMock(self.sut);

    OCMStub([partialMockSUT tableView]).andReturn(mockTableView);

    [self.sut configureTableFooterView];

    OCMVerifyAllWithDelay(mockTableView, 2.0);

    //OCMVerifyAllWithDelay(partialMockSUT, 2.0); 
}

我在同一个类中有另一个测试,它在主线程上的dispatch_async调用中测试与之相同的东西.该测试中的测试期望和验证设置与此匹配.当测试通过时,此测试在延迟的验证步骤中陷入无限循环.

I have another test in the same class which is testing the same things from with in the dispatch_async call on the main thread. The test expectations and verification setup in that test match this one. While that test passes, this one gets stuck in an infinite loop at the delayed verification step.

有趣的是,如果我仅运行此1个测试,那么它不会有任何问题.只有在与其他测试一起运行此测试时,我才发现问题所在.

Interestingly, if I only run this 1 test, it passes with out any problems. Its only when this test is run with other tests that I see the problem.

更新:

在单元测试,使用dispatch_asyc

这是一个更相关的帖子.但是,这几乎与原始测试方法完全失效:

This is a much more relevant post. However, this fails almost in the exact same way as the original test method:

- (void)testTableFooterViewConfigurationAfterLastPageLoaded {

    id mockTableView = OCMClassMock([GMGFlatTableView class]);

    OCMExpect([mockTableView setTableFooterView:[OCMArg isNil]]);

    id resultSet = OCMClassMock([GMGResultSetInfo class]);

    OCMStub([resultSet isLastPage]).andReturn(YES);

    OCMStub([self.mockParser resultSet]).andReturn(resultSet);

    id partialMockSUT = OCMPartialMock(self.sut);

    OCMStub([partialMockSUT tableView]).andReturn(mockTableView);

    [self.sut configureTableFooterView];

    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];

    OCMVerifyAll(mockTableView);
}

作为套件运行时,带有NSRunLoop的行因EXC_BAD_ACCESS而崩溃,但单独运行就可以了!

The line with NSRunLoop crashes with EXC_BAD_ACCESS when run as suite but runs fine alone!

推荐答案

您可以围绕dispatch_async进行类包装,并将其作为依赖项传递.您也可以制作假包装,并在测试中将其通过.如果您有兴趣,我可以提供更详细的解释.

You can make class wrapper around dispatch_async, and pass it as dependency. Also you can make fake wrapper, and pass it in tests. If you interested in, I can provide much more detailed explanation.

这篇关于iOS-单元测试异步代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆