ASP.NET Core Integration Testing & Mocking using Moq

If you want to run an integration test for your ASP.NET Core app without also testing lots of external dependencies like databases and the like, then the lengthy official ‘Integration tests in ASP.NET Core‘ documentation shows how you can use stubs to replace code that talks to a database or some other external service. If you want to use mocks, this is where you run out of guidance and runway. It does in fact require a fair amount of setup to do it correctly and reliably without getting flaky tests.


The ConfigureServices and Configure methods in your applications Startup class must be virtual. This is so that we can iherit from this class in our tests and replace production versions of certain services with mock versions.


In your test project, inherit from the Startup class and override the ConfigureServices method with one that registers the mock and the mock object with IoC container.

I like to use strict mocks using MockBehavior.Strict, this ensures that nothing is mocked unless I specifically setup a mock.


In your test project, write a custom WebApplicationFactory that configures the HttpClient and resolves the mocks from the TestStartup, then exposes them as properties, ready for our integration test to consume them. Note that I’m also changing the environment to Testing and telling it to use the TestStartup class for startup.

Note also that I’ve implemented IDisposable‘s Dispose method to verify all of my strict mocks. This means I don’t need to verify any mocks manually myself. Verification of all mock setups happens automatically when xUnit is disposing the test class.

Integration Tests

I’m using xUnit to write my tests. Note that the generic type passed to CustomWebApplicationFactory is Startup and not TestStartup. This generic type is used to find the location of your application project on disk and not to start the application.

I setup a mock in my test and I’ve implemented IDisposable to verify all mocks for all my tests at the end but you can do this step in the test method itself if you like.

Note also, that I’m not using xUnit’s IClassFixture to only boot up the application once as the ASP.NET Core documentation tells you to do. If I did so, I’d have to reset the mocks between each test and also you would only be able to run the integration tests serially one at a time. With the method below, each test is fully isolated and they can be run in parallel. This uses up more CPU and each test takes longer to execute but I think it’s worth it.


I’m using xUnit. We need to turn off shadown copying, so any separate files like appsettings.json are placed in the right place beside the application DLL file. This ensures that our application running in an integration test can still read the appsettings.json file.


Should you have configuration that you want to change just for your integration tests, you can add a appsettings.Testing.json file into your application. This configuration file will only be read in our integration tests because we set the environment name to ‘Testing’.

Working Examples

If you’d like to see an end to end working example of how this all works. You can create a project using the Dotnet Boxed API project template or the GraphQL project template.


I wrote this because there is little to no information on how to combine ASP.NET Core with Moq in integration tests. I’ve messed about with using IClassFixture as the ASP.NET Core documentation tells you to do and it’s just not a good idea with Moq which needs a clean slate before each test. I hope this stops others going through much pain.