Интеграционный тест: контроллеру API не удалось вызвать другой контроллер через ASP.NET Core API - PullRequest
0 голосов
/ 15 декабря 2018

У меня проблема с получением контроллера API для вызова другого контроллера API в том же проекте.

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

Однако первый контроллер может вызывать google.com.

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

Производственный проект представляет собой проект ASP.NET CORE Web API v2.1 и проект интеграционного тестирования v2.1 через xUnit, выполнив следующие действия

https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2

Проект интеграции с xUnit ниже:

public class RetryPolicyTests: IClassFixture<WebApplicationFactory<Startup>>
    {
        private readonly WebApplicationFactory<Startup> _factory;

        public RetryPolicyTests(WebApplicationFactory<Startup> factory)
        {
            _factory = factory;
        }

        [Theory]
        [InlineData("http://localhost:1234/api/v1/Book/")]        
        public async Task Test(string url)
        {
            // Arrange
            var client = _factory.CreateClient();

            // Act           

            var body = "{}";
            using (var content = new StringContent(body, Encoding.UTF8, "application/json"))
            {

                var response = await client.PostAsync(url, content);

                // Assert
                response.EnsureSuccessStatusCode(); //Failed here with internal server error
                Assert.Equal(StatusCodes.Status200OK,
                    (int) (response.StatusCode));
            }
        }
    }

BookController

  [ApiVersion("1")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    public class BookController : ControllerBase
    {
        private readonly ILog _logger;
        private readonly IConfiguration _configuration;
        private IHttpClientFactory _httpClientFactory;

        public BookController(ILog logger , IConfiguration configuration, IHttpClientFactory httpClientFactory)
        {
            _logger = logger;            
            _configuration = configuration;
            _httpClientFactory = httpClientFactory;
        }


        [HttpPost]
        public async Task<ActionResult> Post()
        {           
            using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
            {
                string body = reader.ReadToEnd();

                var url = "http://localhost:1234/api/v1/Author/"
                using (var content = new StringContent(body, Encoding.UTF8, "application/json"))
                {                    
                    var _httpClient = _httpClientFactory.CreateClient();
                    var s = _httpClient.GetAsync("http://google.com").Result;  //works here

                    var response = await _httpClient.PostAsync(url, content);   //internal server error
                     var statusCode = response.StatusCode;
                    return StatusCode((int)statusCode);
                }

            }      
        }

    }

AuthorController

 [ApiVersion("1")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]        
public class AuthorController : ControllerBase
{
    ILog _logger;

    public AuthorController(ILog logger)
    {
        _logger = logger;
    }

    [HttpPost]
    public void Post()
    {
        using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
        {
            var body = reader.ReadToEnd();

        }

}

Работает, если интеграциятестирование попаданий непосредственно на контроллере Author.

ошибка:

Result StackTrace:  
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at IntegrationTests.xUnit.RetryPolicy.RetryPolicyTests.Test(String url) in C:\IntegrationTests.xUnit\RetryPolicy\RetryPolicyTests.cs:line 46
--- End of stack trace from previous location where exception was thrown ---
Result Message: System.Net.Http.HttpRequestException : Response status code does not indicate success: 500 (Internal Server Error).

обновление

Обратите внимание, что после интеграционного теста попадет первый контроллер и до попаданийНа втором контроллере я пытался отправить те же данные на первый контроллер с помощью внешних инструментов, таких как Postman или Fiddler.Но все контроллеры не доступны для внешнего инструмента, в отличие от того, находится ли он на консоли или в службе Windows (в этом случае все контроллеры могут обрабатывать запросы).

https://github.com/aspnet/AspNetCore/issues/5132

Обновление

Я обновился до 2.2, проблема все еще существует

Обновление

System.Net.Http.HttpRequestException: No connection could be made because the target machine actively refused it ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result()
at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.get_Result()
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Controllers.BookController.Post() in C:\src\Controllers\BookController.cs:line 84} System.Exception {System.Net.Http.HttpRequestException}

InnerException {System.Net.Sockets.SocketException (10061): No connection could be made because the target machine actively refused it
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)} System.Exception {System.Net.Sockets.SocketException}
...