Visual Studio 2013 年使用 HttpClient 进行单元测试/集成测试 Web API

Unit Testing / Integration Testing Web API with HttpClient in Visual Studio 2013

我很难用 Visual Studio 2013 测试我的 API 控制器。我的一个解决方案有一个 Web API 项目和一个测试项目。在我的测试项目中,我有一个单元测试:

[TestMethod]
public void GetProduct()
{
    HttpConfiguration config = new HttpConfiguration();
    HttpServer _server = new HttpServer(config);

    var client = new HttpClient(_server);

    var request = new HttpRequestMessage
    {
        RequestUri = new Uri("http://localhost:50892/api/product/hello"),
        Method = HttpMethod.Get
    };

    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    using (var response = client.SendAsync(request).Result)
    {
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

        var test = response.Content.ReadAsAsync<CollectionListDTO>().Result;
    }
}

我一直收到 404。我已经尝试 运行 将我的 API 与 Visual Studio (IIS Express) 的一个实例结合使用,并尝试在另一个实例中调试此单元测试。但没有运气。我已经验证我可以将这个 URL 放在浏览器中(当一个 Visual Studio 正在调试时)并且我看到了我的 JSON 响应。但是我不知道如何让它与我的单元测试和 HttpClient 一起工作。我试图在网上找到示例,但似乎找不到。有人可以帮忙吗?

更新 1: 我尝试添加路线但没有任何反应。

HttpConfiguration config = new HttpConfiguration();

// Added this line
config.Routes.MapHttpRoute(name: "Default", routeTemplate: "api/product/hello/");

HttpServer _server = new HttpServer(config);

var client = new HttpClient(_server);

[...rest of code is the same]

这是我的 API 控制器

[HttpGet]
[Route("api/product/hello/")]
public IHttpActionResult Hello()
{
     return Ok();
}

更新分辨率: 如果我在没有 HttpServer 对象的情况下新建 HttpClient,我就能让它工作。不过,我仍然需要有两个 VS 运行ning 实例。 1 运行宁我的 API 代码和另一个 运行 单元测试。

这是一个工作方法。

[TestMethod]
public void Works()
{
    var client = new HttpClient(); // no HttpServer

    var request = new HttpRequestMessage
    {
        RequestUri = new Uri("http://localhost:50892/api/product/hello"),
        Method = HttpMethod.Get
    };

    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    using (var response = client.SendAsync(request).Result)
    {
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }
}

任何人都知道为什么它不能使用 HttpServerHttpConfiguration 传递给 HttpClient?我见过很多使用这个的例子。

参考以下文章我能够做到...

ASP.NET Web API integration testing with in-memory hosting

通过使用 HttpServerHttpConfiguration 传递给 HttpClient。在下面的示例中,我创建了一个使用属性路由的简单 ApiController。我配置 HttpConfiguration 来映射属性路由,然后将其传递给新的 HttpServerHttpClient 然后可以使用配置的服务器对测试服务器进行集成测试调用。

public partial class MiscUnitTests {
    [TestClass]
    public class HttpClientIntegrationTests : MiscUnitTests {

        [TestMethod]
        public async Task HttpClient_Should_Get_OKStatus_From_Products_Using_InMemory_Hosting() {

            var config = new HttpConfiguration();
            //configure web api
            config.MapHttpAttributeRoutes();

            using (var server = new HttpServer(config)) {

                var client = new HttpClient(server);

                string url = "http://localhost/api/product/hello/";

                var request = new HttpRequestMessage {
                    RequestUri = new Uri(url),
                    Method = HttpMethod.Get
                };

                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                using (var response = await client.SendAsync(request)) {
                    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
                }
            }
        }
    }

    public class ProductController : ApiController {
        [HttpGet]
        [Route("api/product/hello/")]
        public IHttpActionResult Hello() {
            return Ok();
        }
    }
}

无需另一个 VS 实例 运行 即可对控制器进行集成测试。

以下简化版本的测试也有效

var config = new HttpConfiguration();
//configure web api
config.MapHttpAttributeRoutes();

using (var server = new HttpServer(config)) {

    var client = new HttpClient(server);

    string url = "http://localhost/api/product/hello/";

    using (var response = await client.GetAsync(url)) {
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }
}

在您的情况下,您需要确保正确配置服务器以匹配您的网络 api 设置。这意味着您必须使用 HttpConfiguration 对象注册您的 api 路由。

var config = new HttpConfiguration();
//configure web api
WebApiConfig.Register(config);
//...other code removed for brevity