For in-memory server testing The following utility class was created. It basically wraps the setup functionality in the example shown.
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);
}
}
The following test was crafted to demonstrate the use of in memory server using 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();
}
}
}
Test passes.
The thing about this example is that the test and controller exist in same assembly so map attribute scans the assembly it was called in and found API controller with attribute routes. If controller lived in another project then the web API config of that project should be called on the HttpConfiguration to properly configure web API.
UPDATE
The test project and web api project should be two separate projects. That said, The web project should have a WebApiConfig.cs file with a static WebApiConfig.Register class and method. That method takes a HttpConfiguration parameter. The test should use that method to configure the api for in memory calls.
[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);
}
}
}
http://localhost/test/testassuming that the route was {controller}/{action}