在 Visual Studio 2013 中使用 HttpClient 进行单元测试/集成测试 Web API [英] Unit Testing / Integration Testing Web API with HttpClient in Visual Studio 2013
问题描述
我很难用 Visual Studio 2013 测试我的 API 控制器.我的一个解决方案有一个 Web API 项目和一个测试项目.在我的测试项目中,我有一个单元测试:
I am having a hard time trying to test my API controller with Visual Studio 2013. My one solution has a Web API Project and a Test project. In my test project, I have a Unit Test with this:
[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.我曾尝试使用 Visual Studio (IIS Express) 的一个实例运行我的 API,并尝试在另一个实例中调试此单元测试.但没有运气.我已经验证我可以将此 URL 放在浏览器中(当一个 Visual Studio 正在调试时)并且我看到了我的 JSON 响应.但我不知道如何让它与我的单元测试和 HttpClient
一起工作.我试图在网上找到示例,但似乎找不到.有人可以帮忙吗?
I keep getting a 404. I have tried running my API with one instance of Visual Studio (IIS Express), and trying to debug this Unit Test in another instance. But no luck. I have verified that I can put this URL in a browser (when one Visual Studio is debugging) and I see my JSON response. But I can't figure out how to get it to work with my unit test and HttpClient
. I have tried to find examples online but can't seem to find one. Can someone help?
更新 1:我尝试添加一条路线,但没有任何反应.
UPDATE 1: I tried adding in a route but nothing happened.
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 控制器
Here is my API Controller
[HttpGet]
[Route("api/product/hello/")]
public IHttpActionResult Hello()
{
return Ok();
}
更新解决方案:如果我在没有 HttpServer
对象的情况下新建 HttpClient
,我就能让它工作.不过,我仍然需要运行两个 VS 实例.1 运行我的 API 代码,另一个运行单元测试.
UPDATE Resolution:
I was able to get it to work if I new up HttpClient
without a HttpServer
object. I would still need to have two instances of VS running though. 1 running my API code and another to run the Unit Test.
这是一种工作方法.
[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
?我见过很多使用这个的例子.
Anyone know why it doesn't work with a HttpServer
and a HttpConfiguration
passed into HttpClient
? I have seen many examples that use this.
推荐答案
参考以下文章我能够做到...
Referencing the following article I was able to do...
通过使用传递给 HttpClient
的 HttpServer
和 HttpConfiguration
.在以下示例中,我创建了一个使用属性路由的简单 ApiController
.我将 HttpConfiguration
配置为映射属性路由,然后将其传递给新的 HttpServer
.HttpClient
然后可以使用配置的服务器对测试服务器进行集成测试调用.
by working with a HttpServer
and a HttpConfiguration
passed into HttpClient
. In the following example I created a simple ApiController
that uses attribute routing. I configured the HttpConfiguration
to map attribute routes and then passed it to the new HttpServer
. The HttpClient
can then use the configured server to make integration test calls to the test server.
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 实例即可集成测试控制器.
There was no need to have another instance of VS running in order to integration test the controller.
以下简化版的测试效果也很好
The following simplified version of the test worked as well
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 路由.
In your case you need to make sure that you are configuring the server properly to match your web api setup. This would mean that you have to register your api routes with the HttpConfiguration
object.
var config = new HttpConfiguration();
//configure web api
WebApiConfig.Register(config);
//...other code removed for brevity
这篇关于在 Visual Studio 2013 中使用 HttpClient 进行单元测试/集成测试 Web API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!