单元测试/集成在Visual Studio 2013中使用HttpClient测试Web API

duy*_*yen 15 c# unit-testing asp.net-web-api dotnet-httpclient 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我一直得到404.我尝试使用一个Visual Studio实例(IIS Express)运行我的API,并尝试在另一个实例中调试此单元测试.但没有运气.我已经验证我可以将此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]
Run Code Online (Sandbox Code Playgroud)

这是我的API控制器

[HttpGet]
[Route("api/product/hello/")]
public IHttpActionResult Hello()
{
     return Ok();
}
Run Code Online (Sandbox Code Playgroud)

更新解决方案: 如果我在HttpClient没有HttpServer对象的情况下新建,我能够让它工作.我仍然需要运行两个VS实例.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);
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都知道为什么它不适用于HttpServerHttpConfiguration传入HttpClient?我见过很多使用它的例子.

Nko*_*osi 25

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

使用内存中托管的ASP.NET Web API集成测试

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

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

为了集成测试控制器,不需要运行另一个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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我只是遇到了完全相同的问题,当我只调用`config.MapHttpAttributeRoutes()时,我的路由/控制器没有被发现.当我通过调用例如`WebApiConfig.Register(config);`添加对我的WebApi项目的显式引用时,它可以工作!(只添加`var ctrl = new ValuesController();`也可以!)我的猜测是,这与未使用的程序集有关,运行时没有加载.这意味着未加载WebApi,因此不会扫描和发现路径/控制器 (3认同)