I have the following setup:
1) A base class for API testing
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) An extension of the class for each controller I want to test:
[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
}
}
So I guess the http server responds only to the first query. Why is that, how to fix it, and how could have I known (don't see it anywhere in the documentation)
EDIT
Turns out that the problem comes from instantiating the client HttpMessageInvoker
twice. If I refactor the BasiApiTest
class like the code snippet below, it works fine. However, I am still interested in my questions.
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;
}
}
It turns out that the HttpMessageInvoker
class has 2 constructors:
HttpMessageInvoker(HttpMessageHandler);
HttpMessageInvoker(HttpMessageHandler, Boolean);
The first one is chained to the second one with true
value, so in my case calling new HttpMessageInvoker(server)
is equivalent to new HttpMessageInvoker(server, true)
and according to specification the boolean parameter is a value that indicates whether this instance is responsible for disposing the handler.
What seems unnatural to me is why
However, the first question is a matter of personal opinion, while the second can still be answered for completeness of this topic.