1

我有一个简单的类来执行网络的东西。它是一个单例,它封装NSOperationQueue在其中。当类的用户调用某个方法从网络获取数据时,该类创建适当的操作类实例,继承自NSOperation设置它并添加到执行队列中。显然,这种执行是在分离的线程中异步进行的。从网络NSOperation继承对象获取数据后,通知我的网络类,并通知感兴趣的代表数据完成或错误。

问题是,如何进行单元测试来检查网络类的逻辑?另外,我实际上并不想测试服务器端的行为。我只想用模拟和预定义的答案替换对服务器的实际异步调用,以测试处理程序的行为。我想检查我的课程是如何工作的,而不是服务器端。我理解测试这类东西的常见逻辑,但我对使用 OCMock 有点困惑。最佳答案将是代码示例。我在我的项目中使用 OCUnit 和 OCMock 进行单元测试。

此外,任何文章或 github 链接都是完美的。

4

2 回答 2

3

如果所有异步调用都通过您的类中的内部方法,您可以简单地在您的对象上创建一个部分模拟并在该方法上使用存根/预期。然后,您可以正常调用公共方法并使用模拟来验证是否调用了内部方法。使用部分模拟会阻止调用真正的实现,因此不应发生网络活动。

至于另一半,来自异步操作的回调,只需调用将直接从您的测试中调用的方法,然后通过使用 OCUnit 断言检查其状态来检查您的类是否正确,或者,如果它反过来使用回调,以及另一个模拟。

于 2013-06-02T19:18:38.857 回答
1

所以我知道这是关于 OCMock 的......但我想我会把它放在那里,我用Kiwi成功地做到了这一点,它看起来像这样。

it(@"should refresh the client's temporary API key if it is stale before sending the request", ^{
    ISLDataServiceAdd *addRequest = [ISLDataServiceAdd withRecord:@{ISLFieldContact_FirstName: @"Jason"} table:ISLTableContact];

    [[clientMock shouldEventually] receive:@selector(apiKey) andReturn:VALID_API_KEY];
    [[clientMock shouldEventually] receive:@selector(hasTemporaryAPIKey) andReturn:theValue(YES)];
    [[clientMock shouldEventually] receive:@selector(isTemporaryAPIKeyStale) andReturn:theValue(YES)];
    [[clientMock shouldEventually] receive:@selector(refreshTemporaryAPIKeyAndWait:)];

    [addRequest sendRequestUsingClient:clientMock completion:nil failure:nil];
});

sendRequestUsingClient:completion:failure:是一个异步调用,所以通过shouldEventually与 Kiwi 一起使用,它知道在调用这些选择器之前需要等待一段时间(默认为 1 秒)。

于 2013-06-01T19:23:46.803 回答