C# 使用web请求为函数编写单元测试

C# 使用web请求为函数编写单元测试,c#,.net,unit-testing,.net-4.0,C#,.net,Unit Testing,.net 4.0,这是我想为其编写单元测试的函数: public object RequestAndSerializeJSON(string url, Type type) { var request = (HttpWebRequest)WebRequest.Create(url); request.Accept = "application/json"; var response = request.GetResponse(); using (var responseStrea

这是我想为其编写单元测试的函数:

public object RequestAndSerializeJSON(string url, Type type) {
    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Accept = "application/json";

    var response = request.GetResponse();
    using (var responseStream = response.GetResponseStream())
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(type);
        return serializer.ReadObject(responseStream);
    }
}
我测试这个的第一个想法是为url传递一个包含测试数据的文件路径,但我不能这样做,因为我正在将它强制转换为
HttpWebRequest
,它会抛出一个文件路径错误,因为它会为文件路径创建
FileWebRequest


做这件事的好方法是什么?我正在使用Visual Studio测试工具进行测试。

您需要抽象掉WebRequest对象,以便用模拟对象替换它。

您遇到了问题。正如您所看到的,您的代码做了两件事。它获取请求,然后创建一个对象

如果您想对其进行单元测试,我建议拆分功能(无论如何,这是一件好事)

(经验法则:如果你的函数名很长,使用了“and”一词或描述了多个东西,那么你应该重构它。我们需要责任小的小方法,这样我们可以替换它们或扩展它们,或者将来更容易地用它们做些事情)

类似于

public WebRequest GetRequest(string url);
public object DeSerializeJSON(WebRequest request, Type type);
可能有用


现在,您可以在测试方法中注入模拟请求,并相应地测试功能。

我完全同意McBral和John Saunders的观点。几年前,我编写了一个et al来启用对依赖于这些类的代码的模拟。

为什么仍然对GetRequest的返回类型使用'object',对反序列化json使用参数?两种类型都使用“WebRequest”不是更好吗?谢谢你的建议。我一直倾向于这样做,但功能似乎已经很简单了。我明白为什么现在有必要了。太棒了。谢谢你的链接!