liveBook · Manning

Test

As explained in ASP.NET Core in Action, 3e

A test is an automated program method that evaluates whether application behavior matches an expected result.

A test is an automated method that checks whether application behavior matches an expected result. A test project holds these methods, so you can rerun checks without manually exercising every scenario. In ASP.NET Core, use isolated unit tests for a component’s behavior and integration tests to check how components work together. section 35.1 section 36.0 section 35.0

To run tests, create a test project with the .NET Test SDK, a framework such as xUnit, and its test-runner adapter. Run it with `dotnet test` or the Visual Studio test runner. The project references the application code it tests. section 35.1 section 36.0

Listing 35.4 Unit test for ConvertToGbp using expected arguments
[Fact]                                                       #1
public void ConvertToGbp_ConvertsCorrectly()                 #2
{
    var converter = new CurrencyConverter();                 #3
    decimal value = 3;                                       #4
    decimal rate = 1.5m;                                     #4
    int dp = 4;                                              #4
    decimal expected = 2;                                    #5
 
    var actual = converter.ConvertToGbp(value, rate, dp);    #6
 
    Assert.Equal(expected, actual);                          #7
}
#1 The [Fact] attribute marks the method as a test method.
#2 You can call the test anything you like.
#3 The class to test, commonly called the “system under test”
#4 The parameters of the test that will be passed to ConvertToGbp
#5 The result you expect
#6 Executes the method and captures the result
#7 Verifies that the expected and actual values match; if they don’t, throws an exception

This small currency-conversion test shows the Arrange–Act–Assert pattern: create the converter and inputs, call the method, then compare its result with the expected value. `[Fact]` marks the method as a test; a failed `Assert.Equal` fails that test. section 35.5

Choose inputs that check more than the usual result:

  • Test the happy path with typical, valid values. section 35.5
  • Test edge cases, such as a zero value or an unusually large value. Use an xUnit `[Theory]` with `[InlineData]` to run the same check against several input sets. section 35.5 section 35.6
  • Test invalid inputs and expected failures. For example, a zero exchange rate should cause an `ArgumentException`; `Assert.Throws` checks that the exception occurs. section 35.6

Assert observable behavior rather than unnecessary implementation details. Tests tied too closely to a method’s internals can break after a harmless change. section 35.6

Testing a middleware decision

A health-check middleware returns `pong` for `/ping` and calls the next `RequestDelegate` for another path. Test each branch separately: inspect the response body for `/ping`, and use a flag to verify that the next delegate ran for a nonmatching path. A `DefaultHttpContext` supplies the request and response for these isolated tests. section 36.1

An API controller unit test can call an action directly and check its result. For an invalid request, set a model-state error explicitly and verify the error response: a direct call does not exercise the surrounding routing, model-binding, and filter systems. Keep business logic in services so it can be tested separately from controller orchestration. section 36.2

Isolation does not check the whole application. Integration tests can exercise components in the middleware pipeline; `WebApplicationFactory` can simulate requests and check the resulting responses. section 36.0

For a service that depends on an EF Core `DbContext`, an in-memory SQLite database can keep tests fast and isolated from external database configuration. This is a practical choice for unit tests, not a universal substitute for a production-like database in integration tests. section 36.4

How ASP.NET Core in Action, 3e covers it

How deep it goes
Works through assertions, input selection, middleware, controllers, and database isolation, but defers broader debates about test timing and coverage.
Examples
Uses currency conversion, a health-check middleware, an API controller, and a recipe service backed by an in-memory database.
What it assumes
Assumes basic C# application code while introducing test projects, assertions, and testing terminology from the basics.
What you can do after
Apply it via xUnit and `dotnet test` to check expected results, failures, and isolated ASP.NET Core behavior.
How it connects
Connects unit testing and integration testing to middleware, API controllers, model validation, and Entity Framework Core.

Also explained in

Compare how 53 books explain test →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.