集成测试:API控制器无法通过ASP.NET Core API调用另一个控制器

时间:2018-12-15 16:01:41

标签: c# asp.net-core .net-core asp.net-core-webapi

我在使一个API控制器调用同一项目中的另一个API控制器时遇到问题。

具体来说,集成项目能够调用生产项目中的控制器,并且该控制器将再次调用同一项目中的虚拟控制器,但是第一个控制器因内部服务器错误而失败。

但是,第一个控制器可以调用google.com。

请注意,当通过控制台或Windows服务托管生产项目时,它可以工作。仅在集成项目中的测试运行时才会发生。

生产项目是一个ASP.NET CORE Web API项目v2.1,集成测试项目是通过xUnit v2.1,请按照以下步骤操作

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

与以下xUnit集成的项目:

from threading import Thread
...
class FloodThread(Thread):
    def __init__(self, hn):
        self.hostnum = hn
        Thread.__init__(self)
    def run(self):
        i = int(self.hn[1:])
        hn.cmd('sudo python /home/pox/ext/My_SYNflood_attack.py 10.0.0.%s 10.0.0.253' % self.i)

...

def attack():
    threads = []
    attack_hosts = ['h2','h3','h4','h5','h6','h7','h8','h9','h10','h11','h12','h13','h14','h15',
               'h16','h17','h18','h19','h20','h21','h22','h23','h24','h25','h26','h27','h28']
    for item in attack_hosts:
        hn = net.get(item)
        thread = FloodThread(hn)
        threads.append(thread)
        thread.start()
    for thread in threads:
        thread.wait()
...

BookController

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

AuthorController

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

            }      
        }

    }

如果集成测试直接在Author控制器上命中,那么它将起作用。

错误:

 [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();

        }

}

更新

请注意,在集成测试击中第一个控制器之后,在击中第二个控制器之前,我尝试通过外部工具(如Postman或Fiddler)将相同的数据发送到第一个控制器。但是,与外部工具托管在控制台或Windows服务上不同,所有控制器都不对外部工具可用(在这种情况下,所有控制者都可以处理请求)。

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

更新

我已升级到2.2,问题仍然存在

更新

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).

0 个答案:

没有答案