自动测试ApiController

我有一个ApiController并希望通过包括路由在内的unit testing进行测试。

一个例子:

 [RoutePrefix("prefix")] public class Controller : ApiController { [HttpGet] [Route("{id1}")] public int Add(int id1, [FromUri] int id2) { return id1 + id2; } } 

我现在想测试这种方法。 我明白了,我可以像普通方法一样测试它。 但我还想通过将URL转换为方法参数来测试它。

基本上我想有一个自动测试,我调用一个像prefix/10?id2=5的URL,得到15的结果。这有可能吗?

我为内存中集成测试编写了一个小助手类,可以作为测试套件的一部分进行调用。

 internal interface IHttpTestServer : IDisposable { HttpConfiguration Configuration { get; } HttpClient CreateClient(); } internal class HttpTestServer : IHttpTestServer { HttpServer httpServer; public HttpTestServer(HttpConfiguration configuration = null) { httpServer = new HttpServer(configuration ?? new HttpConfiguration()); } public HttpConfiguration Configuration { get { return httpServer.Configuration; } } public HttpClient CreateClient() { var client = new HttpClient(httpServer); return client; } public void Dispose() { if (httpServer != null) { httpServer.Dispose(); httpServer = null; } } public static IHttpTestServer Create(HttpConfiguration configuration = null) { return new HttpTestServer(configuration); } } 

然后会像这样使用它

 [TestMethod] public async Task HttpClient_Should_Get_OKStatus_From_InMemory_Hosting() { using (var server = new HttpTestServer()) { MyWebAPiProjectNamespace.WebApiConfig.Configure(server.Configuration); var client = server.CreateClient(); string url = "http://localhost/prefix/10?id2=5"; var expected = 15; 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); var result = await response.Content.ReadAsAsync(); Assert.AreEqual(expected, result); } } } 

这将配置一个内存测试服务器,测试可以使用其httpclient进行调用。 它本质上是一个端到端的集成测试。

  1. 使用Microsoft ASP.NET Web API 2.2 OWIN包创建一个OWIN StartUp类:

     public class Startup { public void Configuration(IAppBuilder builder) { var config = new HttpConfiguration(); builder.UseWebApi(config); config.MapHttpAttributeRoutes(); config.EnsureInitialized(); } } 
  2. 在测试中使用Microsoft ASP.NET Web API 2.2 Self Host包(例如,使用NUnit ):

     [Test] [TestCase(10, 5, 15)] [TestCase(1, 2, 3)] // add your test cases public async Task AdditionTests(int a, int b, int result) { // Arrange var address = "http://localhost:5050"; using (WebApp.Start(address)) { var client = new HttpClient(); var requestUri = $"{address}/prefix/{a}?id2={b}"; // Act var response = await client.GetAsync(requestUri); // Assert Assert.IsTrue(await response.Content.ReadAsAsync() == result); } } 

这是一个集成测试,而不是unit testing。 如果你想自动化这个,你必须有一个工具来启动/托管你的web api然后执行针对它的请求。

如果您希望将其保留为unit testing,但可以validation类和方法的属性并检查值。

 var type = typeof(Controller); var attributeRoutePrefix = type.GetCustomAttribute(typeof(RoutePrefixAttribute)) as RoutePrefixAttribute; Assert.IsNotNull(attributeRoutePrefix); Assert.AreEqual("prefix", attributeRoutePrefix.Prefix); var methodAttribute = type.GetMethod(nameof(Controller.Add)).GetCustomAttribute(typeof(RouteAttribute)) as RouteAttribute; Assert.IsNotNull(methodAttribute); Assert.AreEqual("id1", methodAttribute.Template); 

它可以通过使用postman或fiddler来测试url param ..