unit testing/集成在Visual Studio 2013中使用HttpClient测试Web API
我很难用Visual Studio 2013测试我的API控制器。我的解决方案有一个Web API项目和一个测试项目。 在我的测试项目中,我有一个unit testing:
[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().Result; } }
我一直得到404 。 我尝试使用一个Visual Studio实例(IIS Express)运行我的API,并尝试在另一个实例中调试此unit testing。 但没有运气。 我已经validation我可以将此URL放在浏览器中(当一个Visual Studio正在调试时),我看到了我的JSON响应。 但我无法弄清楚如何使用我的unit testing和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实例。 1运行我的API代码,另一个运行unit testing。
这是一种工作方法。
[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); } }
任何人都知道为什么它不能与HttpServer
和传递给HttpClient
的HttpConfiguration
HttpClient
? 我见过很多使用它的例子。
参考以下文章,我能够做到……
使用内存中托管的ASP.NET Web API集成测试
通过使用传递给HttpClient
的HttpServer
和HttpConfiguration
。 在下面的示例中,我创建了一个使用属性路由的简单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(); } } }
为了集成测试控制器,不需要运行另一个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); } }
在您的情况下,您需要确保正确配置服务器以匹配您的Web api设置。 这意味着您必须使用HttpConfiguration
对象注册api路由。
var config = new HttpConfiguration(); //configure web api WebApiConfig.Register(config); //...other code removed for brevity
关于使用HttpServer的问题,我能够使其工作如下:这是在.Net Framework中。 这也可用于测试WebAPI管道集成测试。
public static HttpResponseMessage ConfigureAndAct(string relativeApiUrl, HttpMethod httpMethodType, string bodyForPostMethod, int userid) { var uri = new Uri(string.Concat("http://localhost:10022", relativeApiUrl)); // Todo:Find free port at runtime HttpResponseMessage response; using (HttpConfiguration config = new HttpConfiguration()) { config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; using (HttpRequestMessage request = new HttpRequestMessage() { Content = new StringContent(bodyForPostMethod, Encoding.UTF8, "application/json"), RequestUri = uri, Method = httpMethodType, }) { using (var server = new HttpServer(config)) { using (var client = new HttpClient(server)) { response = client.SendAsync(request, CancellationToken.None).Result; } } } } return response; } // Test GET ----------- //Act var response = ConfigureWebApiForTest.ConfigureAndAct(uriToTest, HttpMethod.Get, string.Empty, userId); var result = response.Content.ReadAsAsync().Result; //Assert Assert.IsTrue(response.StatusCode == HttpStatusCode.OK); Assert.IsNotNull(result); Assert.AreEqual(expectedUrl, result.SomeUrl); // Test POST ------------ // Act HttpResponseMessage response = ConfigureWebApiForTest.ConfigureAndAct(uriToTest, HttpMethod.Post, body, userId); //Assert Assert.IsTrue(response.StatusCode == HttpStatusCode.OK);