2016-11-04 6 views
2

У меня есть ApiController и вы хотите протестировать его с помощью модульных тестов, включая маршрутизацию.Автоматическое тестирование ApiController

Пример:

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

Теперь я хотел бы, чтобы проверить этот метод. Я вижу, что я могу проверить его как обычный метод. Но я также хотел бы протестировать его с переводом URL-адреса на параметры метода.

В принципе, я бы хотел, чтобы у меня был автоматический тест, когда я вызываю URL-адрес, например prefix/10?id2=5 и получаю результат 15. Возможно ли это?

+0

Вы хотите проверить свои маршруты. Это обычная вещь, которую нужно протестировать, есть несколько руководств о том, как это сделать. – Jonesopolis

+0

Исследование TestServer в Web API. Это будет считаться интеграционным тестированием. – Nkosi

ответ

3

я написал небольшой вспомогательный класс для тестирования интеграции в памяти, которую можно назвать как часть испытательного костюма.

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

это будет настроить тестовый сервер в памяти, что тест может совершать звонки на использовании его HttpClient. Это, по сути, комплексный интеграционный тест.

+0

Я не вижу, где это связано с моим классом '' Controller''. – Steffen

+0

Если вы посмотрите на URL-адрес, вы увидите, что он пытается проверить маршрут в вашем контроллере, а также ответ. Это то, что вы хотели в своем вопросе. Я ошибся? – Nkosi

+0

Я думаю, у вас есть ответ, который я ищу. У меня есть проблемы, чтобы запустить его. Я не могу найти WebApiConfig. Также атрибут IntegrationTest ... Думаю, мне это не нужно? – Steffen

1

Его можно с помощью почтальона или скрипача, чтобы проверить с URL-адрес парам ..

+0

.. и как бы вы использовали их в модульном тесте? – stuartd

+0

@stuartd, как только вы начнете тестирование с использованием URL-адресов, вы больше не тестируете устройство. Это называется функциональными/приемными/интеграционными тестами (в зависимости от того, когда вы поступаете), и вы не ограничены одним языком. Я честно не понимаю downvotes, поскольку это метод тестирования legimate с помощью внешних инструментов. – walther

+0

Невозможно выполнить единичный тест, но еще один вариант проверки метода. – Satheshkumar

1

Это тест интеграции, а не единичный тест. Если вы хотите автоматизировать это, у вас должен быть инструмент, который будет запускать/размещать ваш веб-api, а затем выполнять запросы против него.

Если вы хотите сохранить его как единичный тест, хотя вы можете проверить атрибуты класса и метода и проверить значения.

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); 
2
  1. Создание класса OWIN StartUp с использованием Microsoft ASP.NET Web API 2.2 Owin пакет:

    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 Само хост пакет в тестах (используется 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<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); 
        } 
    } 
    
Смежные вопросы