WebApplicationFactory In ASP.NET Core: Practical Tips For C# Developers
Tags: webdev, dotnet, csharp, aspnet
Published: 2024-02-13 17:00:00

The post [WebApplicationFactory in ASP.NET Core: Practical Tips for C# Developers](https://www.devleader.ca/2024/02/09/webapplicationfactory-in-asp-net-core-practical-tips-for-c-developers/) appeared first on [Dev Leader](https://www.devleader.ca).

Testing is an essential part of software development that involves verifying the functionality and performance of an application to ensure it meets the intended purpose. In ASP.NET Core, effective testing can help identify and prevent potential issues before they arise in production environments. In this article, I’ll guide you through working with `WebApplicationFactory` in ASP.NET Core.

The `WebApplicationFactory` is a powerful tool that provides a simplified way to set up and execute integration and unit tests for ASP.NET Core applications. By leveraging the WebApplicationFactory, you can better automate your testing process and achieve consistent testing results. Win-win!

Throughout the article, I’ll provide examples of how to use WebApplicationFactory to create coded tests. If you’re ready to improve your testing with ASP.NET Core, let’s jump in!

---

## Overview of WebApplicationFactory

WebApplicationFactory is a class in the `Microsoft.AspNetCore.Mvc.Testing` namespace that provides a way to create a TestServer instance to host an ASP.NET Core application during testing. It is a powerful tool that simplifies and streamlines the testing process for ASP.NET Core developers.

One of the main advantages of using `WebApplicationFactory` is that it can help test controllers that interact with the rest of the web application. `WebApplicationFactory` creates an in-memory TestServer instance of the web application being tested, providing an environment to test HTTP requests and responses. The in-memory TestServer instance is set up and configured in the same way as a production instance of the web application. This means that `WebApplicationFactory` is helpful for integration tests that call multiple APIs and requires testing of the interaction of different parts in the web application.

`WebApplicationFactory` also has advantages when writing tests isolating parts of your system. It’s possible to test a single function directly without interacting with other parts of the system, such as databases, authentication systems, etc. This makes targeted testing quicker and easier.

`WebApplicationFactory` is simple to use and works entirely within C#. Creating a factory is straightforward. A base class is created with configurations, the `WebApplicationFactory` is used to build the host from these configurations and finally a `HttpClient` can be instantiated. The `HttpClient` is then used to interact with the in-memory TestServer.

[![From Zero to Hero: Integration testing in ASP.NET Core - Dometrain](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/unmgkgu2hutruw8ano28.jpg)](https://dometrain.com/course/from-zero-to-hero-integration-testing-in-asp-net-core?affcode=1115529_nl-teyzg)

It's time to level up! [Check out this course on Dometrain](https://dometrain.com/course/from-zero-to-hero-integration-testing-in-asp-net-core?affcode=1115529_nl-teyzg)!

---

## Writing Unit Tests with WebApplicationFactory

Unit testing is key for software development, particularly in an environment where testing is continuous. These types of tests are lightweight and fast. In ASP.NET Core, unit testing is important to ensure that individual components work as expected. When it comes to ASP.NET Core testing with `WebApplicationFactory`, writing unit tests is easy. `WebApplicationFactory` provides a standardized way to build integration tests, making it easy to write and maintain tests.

### Setting Up Dependencies

To demonstrate the process of writing unit tests with WebApplicationFactory, let’s take an example of a simple test that checks if a controller action returns the correct response. To do this, a test project should be created and the `Microsoft.AspNetCore.Mvc.Testing` package added to the project. The upcoming code examples assume [that xUnit is being used as the testing framework](https://www.devleader.ca/2023/10/08/xunit-and-moq-how-to-master-unit-testing-in-c/).

To test an HTTP endpoint with WebApplicationFactory, a simple test can be written to ensure that the response coming back from our endpoint matches a particular string. Take into account that we should think of issues like the status code, the response’s content, performance, and the feedback to the user if a failure occurs.

### Using HttpClient with WebApplicationFactory

We’ll use an `HttpClient` to send HTTP requests and read HTTP responses from a specific endpoint. It’s a key part of testing with `WebApplicationFactory` since it provides a means to interact with the testing server.

To use `HttpClient` with `WebApplicationFactory`, the `CreateClient()` method must be called from an instance of the factory. This method creates a new client that can be used to send HTTP requests to the in-memory TestServer instance created by `WebApplicationFactory`.

An example of using `HttpClient` with `WebApplicationFactory` is provided below:

```csharp
public class TestFixture : WebApplicationFactory<Startup>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseEnvironment("Testing");
        base.ConfigureWebHost(builder);
    }
}

public class SampleControllerTests : IClassFixture<TestFixture>
{
    private readonly HttpClient _client;

    public SampleControllerTests(TestFixture factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task SampleController_ReturnsOkResult()
    {
        // Arrange
        var request = new HttpRequestMessage(new HttpMethod("GET"), "/api/sample");

        // Act
        var response = await _client.SendAsync(request);

        // Assert
        response.EnsureSuccessStatusCode(); // Status Code 200-299
    }
}
```

In the example above, we use `HttpClient` with `WebApplicationFactory` to test a specific endpoint. Here, a `TestFixture` class inherits from WebApplicationFactory and creates a new instance of `Startup` class by specifying it with the type parameter. Then, the `CreateClient()` method is called to return an `HttpClient` object, which we then use to send an HTTP GET request to a specific endpoint. Finally, we ensure that the status code of the response was a 2xx Success status code.

---

## Integration Testing with WebApplicationFactory

[Integration testing is used to test the interactions between different parts of an application](https://www.devleader.ca/2023/12/02/unit-testing-vs-functional-testing-dev-leader-weekly-20/) and ensure that they work together as expected. In ASP.NET Core, integration testing is particularly important since the framework provides a wide range of tools and components that need to work together seamlessly. The more moving pieces, the more important different types of coverage are!

For integration tests in ASP.NET Core, the `WebApplicationFactory` class creates an in-memory TestServer instance that simulates a production environment and allows you to send requests to the application through the HTTP.Verb methods (i.e GET, POST, DELETE, etc). The tests can be used to evaluate if APIs and database interactions are done correctly, and it allows testing the overall function of the application.

An example of writing an integration test with `WebApplicationFactory` would be to test the interaction between multiple APIs and the database. In this example, we test if a register endpoint accepts new users and their credentials are stored correctly in the database.

```csharp
public class RegisterTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly HttpClient _client;

    public RegisterTests(WebApplicationFactory<Startup> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task Register_ReturnsSuccessResult()
    {
        // Arrange
        var user = new User() { Email = "johndoe@example.com", Password = "testpassword" };
        var payload = JsonConvert.SerializeObject(user);
        var content = new StringContent(payload, Encoding.UTF8, "application/json");

        // Act
        var response = await _client.PostAsync("/api/register", content);

        // Assert
        response.EnsureSuccessStatusCode();
        var responseAsString = await response.Content.ReadAsStringAsync();
        Assert.Contains("Success", responseAsString);
    }
}
```

In the example above, we create a new `WebApplicationFactory` instance of the `Startup` class, then call the `CreateClient()` method to get an instance of `HttpClient` that interacts with the TestServer instance. We test the registration endpoint and verify whether the response returns a success status code.

### Best Practices for Integration Testing with WebApplicationFactory

Here are some best practices for integration testing with `WebApplicationFactory`:

* Use a clean slate for the database: Before running integration tests, make sure to delete any existing test data from the database. This ensures that tests are independent and repeatable.
    
* Use realistic data: Tests should use realistic data that simulates the real-world use of the application.
    
* Test all critical APIs: Tests should cover all critical APIs in the application, including those related to authentication and authorization.
    
* Mock external dependencies: When possible, external dependencies should be mocked to isolate the tests and minimize interference. Otherwise, you can leverage a tool like Testcontainers!
    
* Test edge cases: Edge cases should be tested to ensure that the application can handle unusual inputs and conditions.
    
* Run tests frequently: Tests should be run frequently during the development process to catch issues early and reduce the cost of fixing them. If you have CI/CD, hook these tests up!
    

Integration testing with `WebApplicationFactory` can be a key part of ensuring your ASP.NET Core development goes smoothly. As a C# developer, using `WebApplicationFactory` can simplify the process while allowing for increased efficiency and improved code quality.

[![From Zero to Hero: Integration testing in ASP.NET Core - Dometrain](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/unmgkgu2hutruw8ano28.jpg)](https://dometrain.com/course/from-zero-to-hero-integration-testing-in-asp-net-core?affcode=1115529_nl-teyzg)

It's time to level up! [Check out this course on Dometrain](https://dometrain.com/course/from-zero-to-hero-integration-testing-in-asp-net-core?affcode=1115529_nl-teyzg)!

---

## Mocking Dependencies in Tests with WebApplicationFactory

Mocking dependencies in testing is a technique that isolates the code being tested from external dependencies, such as databases or web APIs. This helps simplify tests and allows developers to test individual components independently. Mocking dependencies is especially important in integration testing, where tests often rely on several different components. Mocking allows developers to isolate the component being tested and verify that it works as intended.

In ASP.NET Core development, `WebApplicationFactory` provides a way to mock dependencies in tests. The `WebApplicationFactory<TStartup>` class can be overridden to create a new instance of the `HttpClient` class that can be used in the tests.

Here’s an example of how to use `WebApplicationFactory` to mock a dependency in an ASP.NET Core application:

```csharp
public class SampleServiceTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly HttpClient _client;

    public SampleServiceTests(WebApplicationFactory<Startup> factory)
    {
        _client = factory
            .WithWebHostBuilder(builder =>
            {
                builder.ConfigureTestServices(services =>
                {
                    services.AddTransient<ISampleDependency, MockSampleDependency>();
                });
            })
            .CreateClient();
    }

    [Fact]
    public async Task Sample_Service_Calls_Dependency()
    {
        // Arrange
        var request = new HttpRequestMessage(new HttpMethod("GET"), "/api/sample");

        // Act
        var response = await _client.SendAsync(request);

        // Assert
        response.EnsureSuccessStatusCode();
    }
}
```

In the example above, we override an instance of an `ISampleDependency` implementation with a mocked version using the `ConfigureTestServices` method inside the `WebApplicationFactory` class. Then, we create a new instance of `HttpClient` that includes the mocked dependency. Finally, it is used to send the HTTP GET request to the required endpoint.

### Using the WebApplicationFactory.CreateClient Method

`WebApplicationFactory` provides a simple way to mock dependencies in tests using the `CreateClient` method. `CreateClient` creates a new instance of `HttpClient` that can be used to communicate with the in-memory TestServer instance created by `WebApplicationFactory`. We can layer in [the Moq nuget package to assist us here](https://www.devleader.ca/2023/10/08/xunit-and-moq-how-to-master-unit-testing-in-c/)!

Here’s an example of how to use `WebApplicationFactory.CreateClient` to mock a dependency in an ASP.NET Core application:

```csharp
public class SampleControllerTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly HttpClient _client;

    public SampleControllerTests(WebApplicationFactory<Startup> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task Sample_Controller_Dependency_Mock()
    {
        // Arrange
        var mockDependency = new Mock<IDependency>();
        mockDependency.Setup(m => m.GetResult()).Returns("Mocked result");

        // Act
        var response = await _client.GetAsync("/api/sample");

        // Assert
        response.EnsureSuccessStatusCode();
        var responseContent = await response.Content.ReadAsStringAsync();
        Assert.Contains("Mocked result", responseContent);
    }
}
```

In the example above, a new instance of `HttpClient` is created using `WebApplicationFactory.CreateClient`, and a mocked dependency is injected into the test by overriding the implementation of the `IDependency` interface. The test verifies that the endpoint returns the expected response with the overridden implementation.

---

## Wrapping Up WebApplicationFactory in ASP.NET Core

Testing is an important part of software development (or at least you should make that the case!), especially in ASP.NET Core. Without proper testing, code can be susceptible to bugs, security issues, and unintended consequences. The `WebApplicationFactory` in ASP.NET Core is a great tool because of its convenience, flexibility, and ease of use.

Using the `WebApplicationFactory` for testing helps you to write effective unit tests and integration tests, including those that test HTTP endpoints. It also allows you to mock dependencies in your applications for more focused testing. I covered how to create a `WebApplicationFactory` instance, write unit tests and integration tests using `WebApplicationFactory`, and mock dependencies with as well!

Remember to consider best practices and remain pragmatic when testing ASP.NET Core applications with `WebApplicationFactory`. Context is key and every situation will be different.

---

### Want More Dev Leader Content?

* Follow along on this platform if you haven’t already!    
* Subscribe to my free weekly software engineering and dotnet-focused newsletter. I include exclusive articles and early access to videos:  
    [**SUBSCRIBE FOR FREE**](https://subscribe.devleader.ca/)    
* Looking for courses? Check out my offerings:  
    [**VIEW COURSES**](https://devleader.ca/courses)    
* E-Books & other resources:  
    [**VIEW RESOURCES**](https://products.devleader.ca/)    
* Watch hundreds of full-length videos on my YouTube channel:  
    [**VISIT CHANNEL**](https://youtube.com/@devleader)    
* Visit my website for hundreds of articles on various software engineering topics (including code snippets):  
    [**VISIT WEBSITE**](https://devleader.ca/)    
* Check out the repository with many code examples from my articles and videos on GitHub:  
    [**VIEW REPOSITORY**](https://github.com/ncosentino/DevLeader)