Skip to content

Xunit Support Classes

Dennis C. Mitchell edited this page Apr 3, 2019 · 19 revisions

EDennis.AspNetCore.Base provides a number of abstract Xunit test classes and supporting classes for performing various kinds of Xunit integration tests. There are four broad categories of integration tests supported: (1) Repo Tests, which directly test repo class methods; (2) Controller Tests, which directly test controller methods (actions); (3) ApiClient Tests, which directly test ApiClient methods; and (4) Endpoint Tests, which test an API endpoint. Only the Endpoint Tests make use of the Microsoft's WebApplicationFactory. All other tests use special factory classes that do not derive from WebApplicationFactory.

Repo Tests

Four abstract classes provide support for testing repo methods. There is one abstract class for each of the four types of repos.

ReadonlyRepoTests Class

This class instantiates a ReadonlyRepo for use in directly testing the repo's public methods. The instantiated repo is exposed as a property called Repo.

Type Parameters

ReadonlyRepoTests has three type parameters.

Type Parameter Constraints
TRepo The type of the instantiated repo, which must extend ReadonlyRepo<TEntity,TContext>
TEntity TEntity is a class with a default constructor
TContext TContext extends Microsoft.EntityFrameworkCore.DbContext

Constructor

ReadonlyRepoTests has a single constructor with two arguments.

Parameter Description
ITestOutputHelper output The Xunit helper class for piping messages to the test output console
ConfigurationFactory<TRepo> fixture A class for finding the applicable appsettings.Development.json file and generating an IConfiguration from that file

Properties

ReadonlyRepoTests exposes two public properties.

Property Description
public TRepo Repo Provides direct access to the Repo object
public ITestOutputHelper Output The Xunit.Abstractions helper object for writing to the test output console

Example

public class TodoRepoTests : ReadonlyRepoTests<
                   TodoRepo, Todo, TodoContext> {
        public TodoRepoTests(ITestOutputHelper output, 
                ConfigurationFactory<TodoRepo> factory)
            : base(output, factory) { }
 // test methods...
}

Example

StateAgencyBackgroundCheckRepoTests

ReadonlyTemporalRepoTests Class

This class instantiates a ReadonlyTemporalRepo for use in directly testing the repo's public methods. The instantiated repo is exposed as a property called Repo.

Type Parameters

ReadonlyTemporalRepoTests has four type parameters.

Type Parameter Constraints
TRepo The type of the instantiated repo, which must extend ReadonlyRepo<TEntity,TContext>
TEntity TEntity is a class with a default constructor and implements IEFCoreTemporalModel
TContext TContext extends Microsoft.EntityFrameworkCore.DbContext (for current records)
THistoryContext THistoryContext extends Microsoft.EntityFrameworkCore.DbContext (for history records)

Constructor

ReadonlyTemporalRepoTests has a single constructor with two arguments.

Parameter Description
ITestOutputHelper output The Xunit helper class for piping messages to the test output console
ConfigurationFactory<TRepo> factory A class for finding the applicable appsettings.Development.json file and generating an IConfiguration from that file

Properties

ReadonlyTemporalRepoTests exposes two public properties.

Property Description
public TRepo Repo Provides direct access to the Repo object
public ITestOutputHelper Output The Xunit.Abstractions helper object for writing to the test output console

Example

public class TodoRepoTests : ReadonlyTemporalRepoTests<
            TodoRepo, Todo, TodoContext, TodoHistoryContext> {
        public TodoRepoTests(ITestOutputHelper output, 
                ConfigurationFactory<TodoRepo> factory)
            : base(output, factory) { }
 // test methods...
}

Example

FederalAgencyBackgroundCheckRepoTests

WriteableRepoTests Class

This class instantiates a WriteableRepo for use in directly testing the repo's public methods. The instantiated repo is exposed as a property called Repo.

Type Parameters

WriteableRepoTests has three type parameters.

Type Parameter Constraints
TRepo The type of the instantiated repo, which must extend WriteableRepo<TEntity,TContext>
TEntity TEntity is a class with a default constructor
TContext TContext extends Microsoft.EntityFrameworkCore.DbContext

Constructor

WriteableRepoTests has a single constructor with two required arguments and one optional argument.

Parameter Required? Description
ITestOutputHelper output Yes The Xunit helper class for piping messages to the test output console
ConfigurationFactory<TRepo> factory Yes A class for finding the applicable appsettings.Development.json file and generating an IConfiguration from that file
string userName No The SysUser value to attached to the updated record (default = "tester@example.org")

Properties

WriteableRepoTests exposes three public properties.

Property Description
public TRepo Repo Provides direct access to the Repo object
public ITestOutputHelper Output The Xunit.Abstractions helper object for writing to the test output console
public string InstanceName The generated name of the in-memory database (a GUID string)

Example

public class TodoRepoTests : WriteableRepoTests<
                   TodoRepo, Todo, TodoContext> {
        public TodoRepoTests(ITestOutputHelper output, 
                ConfigurationFactory<TodoRepo> factory, "bob@example.org")
            : base(output, factory) { }
 // test methods...
}

Example

AgencyOnlineCheckRepoTests

WriteableTemporalRepoTests Class

This class instantiates a WriteableTemporalRepo for use in directly testing the repo's public methods. The instantiated repo is exposed as a property called Repo.

Type Parameters

WriteableTemporalRepoTests has four type parameters.

Type Parameter Constraints
TRepo The type of the instantiated repo, which must extend WriteableTemporalRepo<TEntity,TContext>
TEntity TEntity is a class with a default constructor
TContext TContext extends Microsoft.EntityFrameworkCore.DbContext (for current records)
THistoryContext THistoryContext extends Microsoft.EntityFrameworkCore.DbContext (for history records)

Constructor

WriteableTemporalRepoTests has a single constructor with two required arguments and one optional argument.

Parameter Required? Description
ITestOutputHelper output Yes The Xunit helper class for piping messages to the test output console
ConfigurationFactory<TRepo> factory Yes A class for finding the applicable appsettings.Development.json file and generating an IConfiguration from that file
string userName No The SysUser value to attached to the updated record (default = "tester@example.org")

Properties

WriteableTemporalRepoTests exposes four public properties.

Property Description
public TRepo Repo Provides direct access to the Repo object
public ITestOutputHelper Output The Xunit.Abstractions helper object for writing to the test output console
public string InstanceName The generated name of the in-memory database (current records)
public string HistoryInstanceName The generated name of the in-memory database (history records)

Example

public class TodoRepoTests : WriteableTemporalRepoTests<
                   TodoRepo, Todo, TodoContext, TodoHistoryContext> {
        public TodoRepoTests(ITestOutputHelper output, 
                ConfigurationFactory<TodoRepo> factory, "alice@example.org")
            : base(output, factory) { }
 // test methods...
}

Example

AgencyInvestigatorCheckRepoTests

Controller Tests

EDennis.AspNetCore.Base does not provide any base test classes for testing controller methods directly. Instead, the library provides factory classes that make it easy to instantiate controllers with Repo or ApiClient dependencies in their constructors. The factory classes provide flexibility over base classes -- allowing the developer to inject any number and kind of Repo classes and any number and kind of ApiClient classes into a controller for testing.

TestRepoFactory Class

The TestRepoFactory class provides static methods for instantiating each of the four kinds of repos (readonly, readonly-temporal, writeable, and writeable-temporal), as well as for retrieving the in-memory database name (instance name). This factory class can be used to test controllers that take one or more Repo objects as constructor parameters.

Methods

Type Parameter Constraints
TRepo The type of the instantiated repo, which must extend WriteableTemporalRepo<TEntity,TContext>
TEntity TEntity is a class with a default constructor
TContext TContext extends Microsoft.EntityFrameworkCore.DbContext (for current records)
THistory THistoryContext extends Microsoft.EntityFrameworkCore.DbContext (for history records)
T T is any class in the project that holds the relevant appsettings.Development.json (can be TRepo)
Method
public TRepo CreateReadonlyRepo<TRepo,TEntity,TContext,T>(ConfigurationFactory<T> factory)
public TRepo CreateReadonlyTemporalRepo<TRepo,TEntity,TContext,THistoryContext, T>(ConfigurationFactory<T> factory)
public TRepo CreateWriteableRepo<TRepo,TEntity,TContext,T>(ConfigurationFactory<T> factory, string testUser = DEFAULT_USER)
public TRepo CreateReadonlyRepo<TRepo,TEntity,TContext,THistoryContext,T>(ConfigurationFactory<T> factory, string testUser = DEFAULT_USER)
\\...
\\constructor...
public TodoControllerTests(ITestOutputHelper output, 
                 ConfigurationFactory<TodoController> factory){

    _output = output;

    //create one or more repos using factory method
    _repo = TestRepoFactory.CreateWriteableTemporalRepo<
        TodoRepo, Todo, TodoDbContext, TodoHistoryDbContext, TodoController>(factory);

    //construct a new controller, passing in the repo(s) and a logger
    _ctlr = new TodoController(_repo, new Logger<TodoController>(new LoggerFactory()));
}
\\test methods ...

TestApiClientFactory Class

The TestApiClientFactory class provides static methods for instantiating ApiClients for writeable or readonly endpoints, as well as for retrieving the associated in-memory database name (instance name). This factory class can be used to test controllers that take one or more ApiClient objects as constructor parameters.

Methods

Type Parameter Constraints
TClient The type of the instantiated ApiClient
TStartup The Startup class of the target API to which the ApiClient points
Method
public TRepo CreateReadonlyClient<TClient,TStartup>(ApiLauncherFactory<TStartup> factory)
public TRepo CreateWriteableClient<TClient,TStartup>(ApiLauncherFactory<TStartup> factory, string testUser = DEFAULT_USER)
using A = Namespace.For.TargetApi;
\\...
\\constructor...
public TodoApiClientTests(ITestOutputHelper output, 
                 ApiLauncherFactory<A.Startup> factory){

    _output = output;

    //create one or more API clients using factory method
    _api = TestRepoFactory.CreateWriteableClient<
        TodoApiClient, A.Startup>(factory);

    //construct a new controller, passing in the api client(s) and a logger
    _ctlr = new TodoController(_api, new Logger<TodoController>(new LoggerFactory()));
}
\\test methods ...

ApiClient Tests

(to be continued)

ReadonlyApiClientTests Class

(to be continued)

WriteableApiClientTests Class

(to be continued)

Endpoint Tests

(to be continued)

ReadonlyEndpointTests Class

(to be continued)

ReadonlyTemporalEndpointTests Class

(to be continued)

WriteableEndpointTests Class

(to be continued)

WriteableTemporalEndpointTests Class

(to be continued)

Other Factory and Support Classes

(to be continued)

ConfigurationFactory Class

(to be continued)

ConfiguringWebApplicationFactory Class

(to be continued)

ApiLauncherFactory Class

(to be continued)

TestHttpClientFactory Class

(to be continued)

ClassInfo Class

(to be continued)

Clone this wiki locally