👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Faking Dependencies in Functional testing in ASP.NET WEB API

Faking Dependencies in Functional testing in ASP.NET WEB API

webapi

18 Articles

Improve

In this article, let's learn about how to fake dependencies in Functional Test in WebAPI in ASP.NET Core.

Note: If you have not done so already, I recommend you read the article on Functional testing your ASP.NET WEB API.

Table of Contents

  1. Introduction
  2. Why to Fake Dependencies?
  3. Faking Database
  4. Replacing Services
  5. Summary

Introduction

There are situations where we need to fake dependencies or replace services in our Functional Test. We'll learn about where to place the boundary for integration tests and how this relates to the external dependencies, such as a database, queues, etc. And we'll create a fake for a dependency at that defined boundary.

Let's begin by creating a new test method named GetWeatherForecastFromDatabase, and we'll copy previous test to send the request and deserialize the response. So at this point, running the test results in a failure. Before we complete this test and its implementation, let's review the architecture of the API. We're building a cloud-native web API, so let's imagine that we're going to use some cloud services such as a managed database.

Code Sample - Test to validate data from database

Failing Test

We have WeatherForecastDbContext class in our API project. This is configured with cloud connection string and registed in Program.cs. We are going to inject this into our action method and read the weather forecast data from database. I'm going to get into details of setting up DbContext. I'll cover this in my EntityFramework Learning Path.

Endpoint to return values from Database From Database Endpoint
Swagger output from Endpoint to return values from Database Swagger Response

Why to Fake Dependencies ?

Rather than using services from our real cloud provider in this article, which would complicate the setup to follow along, it's good enough to use our imagination. When working with cloud providers, it's common to use language-specific SDKs that they supply and maintain to code against their managed services. The implementations just hold the data in memory to mimic a real service, and that's sufficient for this scenario.

The benefits of faking in functional tests include:

  • Savings in cost.
  • Faster time to complete the test.
  • Simple & Easy to setup.

Therefore, lets fake these kind of dependencies.

Faking Database

In this example in our API, we are going to use EntityFramework to connect to cloud database. We can fake the database by using an in-memory sqlite database provider to run our tests. Reason to use in memory sqlite provider than in memory database is to make sure relation constraints are working as expected.

  1. Add reference to Microsoft.EntityFrameworkCore.Sqlite Nuget Package in FunctionalTest.csproj.

  2. Add static DatabaseHelper.cs helper class to Initialize and Reset Data for used in tests. Note that these will be used to reset and initialized for each test.

    Code Sample - Database Helper

  3. Finally we need to configure in memory sqlite db in ConfigureTestServices inside WithWebHostBuilder to override the Service Registration in WebApplicationFactory from Program.cs.

    We need to find WeatherForecastDbContext and remove and then create a sqlite in-memory connection and re-register WeatherForecastDbContext with the sqlite in-memory connection. And we are creating a ServiceProvider Scope and get WeatherForecastDbContext from Scope and use that instance to ResetDatabase and InitializeDatabase from DatabaseHelper.cs. This is shown in the below code.

    Code Sample - Custom Web Application Factory

Thats it. We are done with setup. Now the tests will run in the following flow.

  1. Start Test Method.
  2. Create HTTP Client.
  3. Create WebApplicationFactory.
  4. Run Program.cs.
  5. Service Registration.
  6. Overriding Service Registration with ConfigureTestServices.
  7. Build Web Application.
  8. Test Code Execution.

Now lets run the test and see the result.

Passing Test

Replacing Services

Now that we learnt how to fake database. We can also apply the same technique to replace services in our Functional Test. Let's say we have a ExternalAPIService service in our API which implements IExternalAPIService. We can replace this service with a FakeExternalAPIService service in our Functional Test.

All we need to do is to find the ExternalAPIService and remove and then create a FakeExternalAPIService with expected output from that service and re-register ExternalAPIService with FakeExternalAPIService. This is shown in the below code.

Code Sample - Replacing Services

The main drawback of above mentioned approach is it will replace the service implementation for all tests. What if we need to test positive scenario in one test and negative scenario in another test. To do that we can replace service at test level. This can be achieved by adding additional optional IConfiguration? and Action<IServiceCollection>? parameters to RunTest Helper method. We can use the IConfiguration? parameter to get the test Configuration if needed.

Code Sample - Run Test Helper Method with Configuration and ServiceCollection

Now we need to update the Application in CustomWebApplicationFactory to get these two parameters and apply them if they are not null. This is shown in below code.

Code Sample - Custom Web Application Factory with Configuration and ServiceCollection

Now we need to update the test as shown below.

Code Sample - Test to validate data from database with Service Replacement

But this way of replacing services will be difficult to maintain as we need to write a lot of code as replacement service for each scenario and test all scenarios. So I'll teach you another better way in next article.

Summary

In this article, we learnt about how to fake dependencies in Functional Test in WebAPI in ASP.NET Core. We learnt about where to place the boundary for integration tests and how this relates to the external dependencies, such as a database, queues, etc. This idea can be extended and applied to any cloud based dependencies. In our next article, we'll learn about how to Replace services in Functional Test in WebAPI in ASP.NET Core.

👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • Webapi
  • Faking Dependencies
  • Replace Services
  • Functional Test
  • Integration Test