2016-10-21 2 views
2

Когда я закручиваю маршрут /test, он отлично работает, однако тест ниже 404 при попытке попасть на сервер памяти по тому же маршруту.Маршруты неверно отображаются при создании в памяти сервера web api

При проверке _client и _config, похоже, все в порядке - хотя я не уверен, как подтвердить, что мой сервер памяти работает правильно.

Кто-нибудь знает, как я могу получить свой веб-сервер в памяти, чтобы правильно отобразить его маршруты, чтобы мой метод тестирования мог его достичь?

namespace Robo.Tests.Controllers 
{ 

    [TestClass] 
    public class IntegrationTests 
    { 
     private HttpMessageInvoker _client; 
     private HttpConfiguration _config = new HttpConfiguration(); 

     [TestInitialize] 
     public void SetupTest() 
     { 
      _config.MapHttpAttributeRoutes(); 
      _config.EnsureInitialized(); 

      var server = new HttpServer(_config); 
      _client = new HttpMessageInvoker(server); 
     } 

     [TestMethod] 
     public async Task Test() 
     { 
      var result = await _client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "http://localhost/test"), CancellationToken.None); 
     } 
    } 
} 

и контроллер в случае, если вы заинтересованы

namespace Robo.Controllers 
{ 
    //[ValidationActionFilter] 
    public class CVController : ApiController 
    { 

     [HttpGet] 
     [Route("test")] 
     public async Task<IHttpActionResult> test() 
     { 
      return Ok(); 
     } 
    } 
} 
+0

Я считаю, что тестовый сервер в памяти прослушивает localhost. так что это будет 'http: // localhost/test/test', предполагая, что маршрут был {controller}/{action} – Nkosi

+0

просто попытался сменить на localhost и все еще 404ing – Jamesla

+0

Является ли контроллер и тест в той же сборке? Включите определение класса контроллера. – Nkosi

ответ

1

Для сервера в памяти тестирования был создан Следующий класс полезности. Он в основном обертывает функциональность установки в показанном примере.

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

Следующий тест был обработан, чтобы продемонстрировать использование в сервере памяти с помощью OP

[TestClass] 
public class IntegrationTests { 

    [TestMethod] 
    public async Task Test() { 


     using (var server = HttpTestServer.Create()) { 
      //Arrange 
      var config = server.Configuration; 
      config.MapHttpAttributeRoutes(); 
      config.EnsureInitialized(); 

      var client = server.CreateClient(); 
      var url = "http://localhost/test"; 
      var request = new HttpRequestMessage(HttpMethod.Get, url); 
      var expected = System.Net.HttpStatusCode.OK; 

      //Act 
      var result = await client.SendAsync(request, CancellationToken.None); 

      //Assert 
      Assert.IsNotNull(result); 
      Assert.AreEqual(expected, result.StatusCode); 
     } 

    } 

    public class CVController : ApiController { 
     [HttpGet] 
     [Route("test")] 
     public async Task<IHttpActionResult> test() { 
      return Ok(); 
     } 
    } 
} 

Тест проходит.

Дело в этом примере заключается в том, что тест и контроллер существуют в одной и той же сборке, поэтому атрибут map проверяет, на какой сборке он был вызван, и нашел API-контроллер с маршрутами атрибутов. Если контроллер жил в другом проекте, тогда конфигурация веб-API этого проекта должна быть вызвана на HttpConfiguration для правильной настройки веб-API.

UPDATE

АНИ проект тестовый проект и веб должно быть два отдельных проекта. Тем не менее, веб-проект должен иметь файл WebApiConfig.cs со статическим классом и методом WebApiConfig.Register. Этот метод принимает параметр HttpConfiguration. Тест должен использовать этот метод для настройки api для вызовов в памяти.

[TestClass] 
public class IntegrationTests { 

    [TestMethod] 
    public async Task Test() { 


     using (var server = HttpTestServer.Create()) { 
      //Arrange 
      var config = server.Configuration; 
      //Config server 
      MyWebApiNamespace.WebApiConfig.Register(config); 

      var client = server.CreateClient(); 
      var url = "http://localhost/test"; 
      var request = new HttpRequestMessage(HttpMethod.Get, url); 
      var expected = System.Net.HttpStatusCode.OK; 

      //Act 
      var result = await client.SendAsync(request, CancellationToken.None); 

      //Assert 
      Assert.IsNotNull(result); 
      Assert.AreEqual(expected, result.StatusCode); 
     } 
    } 
} 
+0

Хорошо, что вы можете подробно остановиться на том, что вы имели в виду под «Если контроллер жил в другом проекте, тогда веб-API-интерфейс этого проекта должен быть вызван в HttpConfiguration для правильной настройки веб-API ". Я думаю, что это точная проблема, потому что когда я отлаживаю свой сервер, там есть только один маршрут (/) – Jamesla

+0

Используя ваш пример, работая таким образом, чтобы я имел контроллер в том же проекте, так как он будет сидеть в отдельном проекте, как Должен ли я отвечать на конфигурацию веб-api на моем httpconfiguration? – Jamesla

+0

@Jamesla проверить обновленный ответ – Nkosi

Смежные вопросы