如何在客户端MVC客户端项目中模拟Web APi响应(JSON)

时间:2013-09-19 10:41:23

标签: asp.net-mvc-4 asp.net-web-api mocking tdd moq

我想测试调用MVC WebApi的服务代理类并获取JSON响应。

public class CarServiceProxy
{

public CarsCollection GetCars()
    {
        CarsCollection cars = new CarsCollection();

        string api = "api/Car/GetCars";

        var response = httpClient.GetAsync(api).Result;

        if (response.IsSuccessStatusCode)
        {
            cars = response.Content.ReadAsAsync<CarsCollection >().Result;
        }

        return cars;
    }
}

然后我的MVC WebSite控制器类将上述代理类调用为:

public ActionResult Index()
{
    CarsCollection cars = this.carsServiceProxy.GetCars();
    return View(cars);
}

现在要单独测试两者,我可以使用MOQ测试我的控制器并模拟carServiceProxy并在我的测试中使用一些假数据伪造CarsCollection。到目前为止我还好。

但是,如何使用MOQ测试代理类来模拟API响应(JSON)?我想我确实需要测试,因为从JSON到C#的转换发生在该类中,如果有人改变我的模型CarsCollection,那可能会破坏。所以我确实需要测试代理类。

2 个答案:

答案 0 :(得分:1)

您需要为您的客户端创建一个“假”HTTP处理程序。这样,您就可以准确控制返回的HTTP响应。您可以在构造HTTP客户端时注入HTTP处理程序。

对于测试,我通常使用内部构造函数进行测试,它接受HTTP处理程序。这样我就可以轻松地测试我的类,它使用带有假处理程序的HTTP客户端。如果采用这种方法并且单元测试位于单独的程序集中,则需要将以下内容添加到目标项目的AssemblyInfo.cs中:

[assembly: InternalsVisibleTo("NameSpace.MyUnitTestProject")]

假处理程序:

public class FakeHttpMessageHandler : HttpMessageHandler
{
    private HttpResponseMessage _response;

    public FakeHttpMessageHandler(HttpResponseMessage response)
    {
        _response = response;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var responseTask = new TaskCompletionSource<HttpResponseMessage>();
        responseTask.SetResult(_response);

        return responseTask.Task;
    }
}

然后消费(可能想在这里使用JSON序列化助手):

var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(@"{'Cars':[{'Name':'BMW'}]");
var handler = new FakeHttpMessageHandler(response);
var client = new HttpClient(handler);

// client.GetAsync().result will return the response

答案 1 :(得分:0)

您可以将httpClient.GetAsync(api).Result部分更改为moackable和testable以测试代理类。换句话说,您可以使代码独立于HTTP请求响应,只需处理JSON数据以进行测试。