使用NSURLConnection进行单元测试 [英] Unit testing with NSURLConnection
问题描述
我想测试一段使用网络的代码(具体来说是NSURLConnection
类).该代码(简称为NetworkManager
)看起来像这样:
I want to test a piece of code that uses network (the NSURLConnection
class, to be specific). The code (let’s call it NetworkManager
) looks a bit like this:
- (id) buildConnection
{
// some more code and then:
return [NSURLConnection …];
}
- (void) startNetworkSync
{
id connection = [self buildConnection];
//…
}
在单元测试中,我想摆脱网络连接,即.用模拟替换NSURLConnection
对象.我该怎么做?
In the unit test I would like to get rid of the networking, ie. replace the NSURLConnection
object by a mock. How do I do this?
我尝试创建NetworkManager
的部分模拟,该模拟将用存根替换buildConnection
方法.问题是 OCMock 所做的部分模拟仅对来自外部世界的消息进行存根–从startNetworkSync
发送buildConnection
会调用原始方法,而不是存根.
I’ve tried creating a partial mock of the NetworkManager
that would replace the buildConnection
method by a stub. The problem is that partial mocks as done by OCMock only stub messages from the outside world – sending buildConnection
from the startNetworkSync
invokes the original method, not the stub.
我还尝试通过类别对NetworkManager
类进行猴子修补.这行得通,我可以轻松地用其他代码覆盖buildConnection
方法,并用存根替换真正的NSURLConnection
.问题是我发现没有简单的方法可以在测试中获得存根连接-该连接是NetworkManager
的私有部分.
I have also tried monkey-patching the NetworkManager
class through a category. This works, I can easily override the buildConnection
method by other code and replace the real NSURLConnection
with a stub. The problem is that I found no simple way I could get the stubbed connection in the test – the connection is a private part of the NetworkManager
.
然后,我可以将NetworkManager
子类化,重写buildConnection
方法,并为创建的连接添加实例变量和访问器.不过,这似乎是很多代码.
Then I could subclass the NetworkManager
, override the buildConnection
method and add an instance variable plus an accessor for the created connection. This seems like a lot of code, though.
您将如何解决?我正在寻找一种解决方案,以保持NetworkManager
类的设计整洁,并且在测试中不需要太多魔术或代码.
How would you solve this? I am looking for a solution that keeps the NetworkManager
class design clean and does not require much magic nor much code in the test.
推荐答案
这是依赖注入旨在解决的问题;如果使用startNetworkSyncWithConnection:(NSURLConnection*)
,则可以通过模拟连接轻松测试该方法.如果您不想为客户更改API,则甚至可以保留startNetworkSync
作为包装器,该包装器除了以[self buildConnection]
作为参数调用该新方法外,什么也不做.
This is the kind of thing dependency injection is designed to solve; if you use startNetworkSyncWithConnection:(NSURLConnection*)
instead you can easily test the method with a mock connection. If you don't want to change the API for your clients you could even keep startNetworkSync
as a wrapper that does nothing but call that new method with [self buildConnection]
as the argument.
这篇关于使用NSURLConnection进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!