1

考虑以下单元测试:

- (void)testSample {
    XCTestExpectation *expectation = [self expectationWithDescription:@"Sample"];

    [self.manager loadAllSuccess:^{
        [expectation fulfill];

        NSArray *data = [self.manager dataForIndex:0];

        // Correct count of data is 10, not 44 - this should fail.
        XCTAssertEqual(44, data.count);
    } failure:^(NSError *error) {
        [expectation fulfill];

        XCTFail(@"Error encountered");
    }];

    [self waitForExpectationsWithTimeout:60 handler:nil];
}

我在已知的失败案例中遇到了一些问题。测试成功完成,尽管数据数组中应该只有 10 个项目。

如果我把[expectation fulfill]调用放在块的底部,在XCTAssertEqual(44, data.count)方法调用之后,测试会按预期工作并失败,直到我将值更正为 10。

这是一个已知的问题?我一直无法阅读文档说我应该在最后一刻打电话给...

4

2 回答 2

2

根据http://nshipster.com/xctestcase/

总是在异步回调结束时调用fulfill()——提前实现期望可以设置一个竞争条件,运行循环可能在完成测试之前退出。如果测试有多个期望,它不会通过,除非每个期望在 waitForExpectationsWithTimeout() 指定的超时时间内执行fulfill()。

刚刚发现这个 - 不确定它是否 100% 准确,因为我在其他地方看不到任何其他文件说明这一点。

于 2017-02-16T01:38:45.727 回答
0

是的,您应该只fulfill在您的期望得到满足时才打电话。如果您希望您的断言在测试结束之前已经执行,那么您必须仅在断言执行后才满足您的期望。

正如@Zach 的回答所述,引用NSHipster,测试完全有可能在您的成功/失败块完成之前停止执行,因为测试唯一等待的是期望得到满足。在不知道测试的情况下执行成功和失败块。一旦满足预期,测试执行将停止,任何进一步的代码都可能不会执行。

你的代码在成功和失败的情况下都满足了预期,所以不管结果如何,这个测试似乎总是会通过。我建议您将可以满足期望的位置限制在一个位置,这样您就可以知道测试通过时什么在起作用,而在测试失败时什么出了问题,而无需进一步调试。您应该将此测试一分为二,一个是在成功块中满足期望但在失败块中不满足期望,反之亦然在第二个测试中。

于 2017-02-16T08:29:50.513 回答