Automatic testing of ApiController

前端 未结 4 1902
悲哀的现实
悲哀的现实 2021-01-23 06:35

I have an ApiController and would like to test it with unit tests including the routing.

An example:

[RoutePrefix(\"prefix\")]
public class          


        
相关标签:
4条回答
  • 2021-01-23 06:42

    Its possible by using postman or fiddler to test with url param..

    0 讨论(0)
  • 2021-01-23 06:54
    1. Create an OWIN StartUp class using Microsoft ASP.NET Web API 2.2 OWIN package:

      public class Startup
      { 
          public void Configuration(IAppBuilder builder)
          {
              var config = new HttpConfiguration();
      
              builder.UseWebApi(config);
      
              config.MapHttpAttributeRoutes();
              config.EnsureInitialized();
          }
      }
      
    2. Use Microsoft ASP.NET Web API 2.2 Self Host package in your tests (used NUnit for example):

      [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<Startup>(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<int>() == result);
          }
      }
      
    0 讨论(0)
  • 2021-01-23 07:01

    That is an integration test, not a unit test. If you wanted to automate this you would have to have a tool that would launch/host your web api and then execute requests against it.

    If you wanted to keep it as a unit test though you could validate the attributes on the class and the method and check the values.

    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);
    
    0 讨论(0)
  • 2021-01-23 07:05

    I wrote a little helper class for in-memory integration testing that can be called as part of the test suit.

    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);
        }
    }
    

    And would then use it like this

    [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<int>();
                Assert.AreEqual(expected, result);
            }
        }
    }
    

    This will configure an in-memory test server that the test can make calls to using its httpclient. It is in essence an end-to-end integration test.

    0 讨论(0)
提交回复
热议问题