HttpServer上的第二个请求返回503服务不可用

时间:2017-06-18 10:24:04

标签: c# .net httpserver in-memory web-api-testing

我有以下设置:

1)API测试的基类

public class BaseApiTest
{
    private static readonly Uri BaseUri = new Uri("http://localhost");
    private static HttpServer _server;

    internal BaseApiTest()
    {
        var config = new HttpConfiguration
        {
            IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
        };

        WebApiConfig.Register(config);
        _server = new HttpServer(config);
    }

    ~BaseApiTest()
    {
        _server.Dispose();
    }

    protected static HttpResponseMessage GetHttpResponseMessageFrom(HttpMethod method, string relativeUri)
    {
        using (var client = new HttpMessageInvoker(_server))
        {
            var absoluteUri = new Uri(BaseUri, relativeUri);

            var message = new HttpRequestMessage(method, absoluteUri);

            var response = client.SendAsync(message, CancellationToken.None);

            return response.Result;
        }
    }

2)我要测试的每个控制器的类的扩展名:

[TestClass]
public class ChemicalApiTest : BaseApiTest 
{
    private const string ControllerRoutePrefix = "/api/customers/316";

    [TestMethod]
    public void SomeTest() {

        // Act
        var response =
            GetHttpResponseMessageFrom(HttpMethod.Get, ControllerRoutePrefix + "/suppliers");
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); // this is OK

        response =
            GetHttpResponseMessageFrom(HttpMethod.Get, ControllerRoutePrefix + "/suppliers");
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); // This fails with 503
    }
}

所以我猜http服务器只响应第一个查询。为什么会这样,如何修复它,以及我怎么知道(不要在文档中的任何地方看到它)

编辑

事实证明问题来自于实例化客户端HttpMessageInvoker两次。如果我重构BasiApiTest类,如下面的代码片段,它可以正常工作。但是,我仍然对我的问题感兴趣。

public class BaseApiTest
{
    private static readonly Uri BaseUri = new Uri("http://localhost");
    private static HttpMessageInvoker _client;

    internal BaseApiTest()
    {
        var config = new HttpConfiguration
        {
            IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
        };

        WebApiConfig.Register(config);
        var server = new HttpServer(config);
        _client = new HttpMessageInvoker(server);
    }

    ~BaseApiTest()
    {
        _client.Dispose();
    }

    protected static HttpResponseMessage GetHttpResponseMessageFrom(HttpMethod method, string relativeUri)
    {
        var absoluteUri = new Uri(BaseUri, relativeUri);

        var message = new HttpRequestMessage(method, absoluteUri);

        var response = _client.SendAsync(message, CancellationToken.None);

        return response.Result;
    }
}

1 个答案:

答案 0 :(得分:2)

事实证明HttpMessageInvoker类有2个构造函数:

foo_original

第一个链接到第二个HttpMessageInvoker(HttpMessageHandler); HttpMessageInvoker(HttpMessageHandler, Boolean); 值,所以在我的情况下,调用true相当于new HttpMessageInvoker(server),根据规范,布尔参数是 value,指示此实例是否负责处理处理程序。

对我来说似乎不自然的是为什么

  1. 默认行为是处置提供的依赖项。
  2. 默认行为未记录。
  3. 然而,第一个问题是个人意见问题,而第二个问题仍然可以回答这个主题的完整性。