Testing an ASP.NET Core application using TestServer

When Microsoft has designed ASP.NET Core, testing was clearly part of the design. Using dependency injection, you can unit test your middlewares and controllers. But you can also use the TestServer to make integration tests. This means you can test your full web application without an IIS server or any external thing. It's a fully in process server. A simple example will be much clearer. Let's use the following controller:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseMvc();
    }
}

[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}
  1. Add a new MSTest project
  2. Add a reference to the web project
  3. Add the NuGet package: Microsoft.AspNetCore.TestHost
  4. Create a test
[TestClass]
public class Tests
{
    [TestMethod]
    public async Task TestMethod1()
    {
        var webHostBuilder =
              new WebHostBuilder()
                    .UseEnvironment("Test") // You can set the environment you want (development, staging, production)
                    .UseStartup<Startup>(); // Startup class of your web app project

        using (var server = new TestServer(webHostBuilder))
        using (var client = server.CreateClient())
        {
            string result = await client.GetStringAsync("/api/values");
            Assert.AreEqual("[\"value1\",\"value2\"]", result);
        }
    }
}

This was a basic example. In a more complex scenario, you may want to replace some service using DI. ASP.NET provides mecanisms to support multiple environments. For instance, you can create one Configure<Environment name>Services method per environment. If no method is defined for the environment, the ConfigureServices will be used. One way to personalize the DI for testing is to create a class that inherits from Startup and add the method ConfigureTestServices:

public class TestStartup : Startup
{
    public TestStartup(IHostingEnvironment env) : base(env)
    {
    }

    public void ConfigureTestServices(IServiceCollection services)
    {
        // Configure services for Test environment
    }
}

Then, use the TestStartup class to initialize the TestServer:

[TestMethod]
public async Task TestMethod1()
{
    var webHostBuilder =
            new WebHostBuilder()
                .UseEnvironment("Test")
                .UseStartup<TestStartup>();
    // ...
}

Test Explorer

This was just a quick introduction to integration testing with ASP.NET Core. You can find more resources in the documentation.

Leave a reply