A test suite is worth having when it tells you something you did not know. Most of the material below is about getting to that point: choosing a framework, faking the awkward dependency, and deciding which tests are worth the trouble of a real database.
The three frameworks come first, because that choice shapes every test you write afterwards and it is annoying to change. Then mocking, then the ASP.NET Core specifics, then the tests that run against real infrastructure.
Time, the file system, the clock and the network are what make a suite flaky. Each has an article here, and each is worth reading before you write the test, not after it starts failing on the build server.
Choosing a Test Framework
xUnit, NUnit and MSTest do the same job with different opinions about setup, parallelism and naming.
- Introduction to Unit Testing With NUnit
- Unit Testing with xUnit
- Differences Between NUnit, xUnit and MSTest
- How to Pass Complex Parameters to Theory in xUnit
Mocking and Fakes
Replacing a dependency with something you control, and the point at which a mock is telling you the design is wrong.
- Effective Mocking With NSubstitute
- Testing Controllers with Unit Tests and Moq
- Seamless Integration Testing With WireMock.NET
- Introduction to Autofac FakeItEasy Package
- Mock Asynchronous Methods Using Moq
- Using Moq to Determine If a Method is Called
- How to Use Moq to Return a Value That Was Passed Into a Method?
- How to Mock the File System for Unit Testing
- How to Mock HttpClient with Unit Tests
- How to Use FakeLogger to Test Logging Code
Assertions and Test Data
Saying what you expected in a way that reads well when it fails, and producing the data to test it with.
- Realistic Data Generation in .NET With Bogus
- Improving Unit Tests with Fluent Assertions
- Test Data Generation With AutoFixture
- How to Use Shouldly to Improve Unit Tests
- How to Perform Snapshot Testing With Verify
Testing ASP.NET Core
Controllers, services and the whole application in memory.
- Unit Testing in ASP.NET Core Web API
- Integration Testing
- Unit Testing in ASP.NET Core MVC
- System Testing a REST API using C# and DalSoft Rest Client
- How to Test gRPC Services
- How to Unit Test ILogger
- How to Test IServiceCollection Registrations
- How to Test a REST API with .NET and xUnit
The Awkward Dependencies: Time, Files and HTTP
Anything your test cannot control is a reason it will fail on somebody else’s machine. Here is the .NET answer to each.
Testcontainers and Real Infrastructure
Running the test against a real database in a container, which is often cheaper than the fake you were about to write.
UI and Browser Testing
Driving a real browser, with the usual warning about how much of your suite should work this way.
- Automated UI Tests with Selenium and ASP.NET Core
- Execute JavaScript Using Selenium WebDriver
- Select a Dropdown Option Using Selenium WebDriver
- How to Maximize the Browser Window With Selenium
Performance and Load Testing
Asking how fast rather than whether it works.
- Performance Testing of ASP.NET Core APIs With k6
- Load Testing ASP.NET Core Web API With JMeter
- How to Integrate BenchmarkDotNet With Unit Tests
Coverage and Practices
Measuring what the suite touches, and the practices around writing it.
Where to Go Next
What you are usually testing:
A test that has never failed has never been checked. Break the code on purpose once and watch it go red, then you know what it is actually asserting.
