Technical Specification for Setting Up a Testing Environment with .NET 8.0 - wwestlake/Labyrinth GitHub Wiki
This specification outlines the setup process for a comprehensive testing environment using xUnit for unit testing, Moq and Moq.AutoMock for mocking dependencies, Coverlet for code coverage, and Mongo2Go for in-memory MongoDB testing. This environment will enable effective and isolated unit tests for Web APIs and services that interact with MongoDB. The instructions cover both command-line setup and setup using the Visual Studio 2022 User Interface.
Ensure you have the following installed:
- .NET SDK (version 8.0 or later)
- Visual Studio 2022 (or any other compatible IDE)
- MongoDB installed locally for development (optional, if Mongo2Go will always be used)
First, create a new test project in your solution using the command line:
dotnet new xunit -n Labyrinth.API.UnitTests
dotnet add Labyrinth.API.UnitTests reference Labyrinth.API
Navigate to your test project folder and install the following NuGet packages using the command line:
cd Labyrinth.API.UnitTests
dotnet add package xunit --version 2.4.1
dotnet add package Moq --version 4.16.1
dotnet add package Moq.AutoMock --version 1.4.0
dotnet add package Coverlet.Collector --version 3.1.2
dotnet add package Mongo2Go --version 2.2.29
-
Open Your Solution: Launch Visual Studio 2022 and open your existing solution or create a new one.
-
Add a New Project:
- Right-click on your solution in the Solution Explorer.
- Select Add > New Project.
- In the New Project dialog, search for "xUnit Test Project".
- Select xUnit Test Project (.NET Core) and click Next.
- Name the project
Labyrinth.API.UnitTests
and click Create. - Choose
.NET 8.0
as the target framework if prompted.
-
Reference the Main Project:
- Right-click on the newly created
Labyrinth.API.UnitTests
project. - Select Add > Project Reference....
- Check the box next to your main project (
Labyrinth.API
) and click OK.
- Right-click on the newly created
-
Open the NuGet Package Manager:
- Right-click on the
Labyrinth.API.UnitTests
project in the Solution Explorer. - Select Manage NuGet Packages....
- Right-click on the
-
Install Packages:
- Go to the Browse tab and search for each of the following packages:
xunit
Moq
Moq.AutoMock
Coverlet.Collector
Mongo2Go
- Select each package and click Install. Confirm any prompts to accept license agreements.
- Go to the Browse tab and search for each of the following packages:
-
Edit the Project File:
- Right-click on the
Labyrinth.API.UnitTests
project in Solution Explorer. - Select Edit Project File.
- Add the following lines to include the Coverlet collector:
- Right-click on the
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="Moq.AutoMock" Version="1.4.0" />
<PackageReference Include="Coverlet.Collector" Version="3.1.2" />
<PackageReference Include="Mongo2Go" Version="2.2.29" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="coverlet" Version="3.1.2" />
</ItemGroup>
</Project>
- Save and Close the project file.
-
Create a Helper Class:
- Right-click on the
Labyrinth.API.UnitTests
project in Solution Explorer. - Select Add > Class....
- Name the class
MongoDbFixture.cs
and click Add. - Implement the
MongoDbFixture
class as shown below:
- Right-click on the
using Mongo2Go;
using MongoDB.Driver;
public class MongoDbFixture : IDisposable
{
public MongoDbRunner Runner { get; private set; }
public IMongoClient Client { get; private set; }
public IMongoDatabase Database { get; private set; }
public MongoDbFixture()
{
Runner = MongoDbRunner.Start();
Client = new MongoClient(Runner.ConnectionString);
Database = Client.GetDatabase("LabyrinthTestDb");
}
public void Dispose()
{
Runner.Dispose();
}
}
-
Create a Test Class:
- Right-click on the
Labyrinth.API.UnitTests
project in Solution Explorer. - Select Add > Class....
- Name the class
CharacterServiceTests.cs
and click Add.
- Right-click on the
-
Implement the Test Class:
using Xunit;
using Moq;
using Moq.AutoMock;
using Labyrinth.API.Services;
using Labyrinth.API.Entities.Characters;
using MongoDB.Driver;
using System.Threading.Tasks;
public class CharacterServiceTests : IClassFixture<MongoDbFixture>
{
private readonly MongoDbFixture _mongoDbFixture;
private readonly AutoMocker _mocker;
public CharacterServiceTests(MongoDbFixture mongoDbFixture)
{
_mongoDbFixture = mongoDbFixture;
_mocker = new AutoMocker();
}
[Fact]
public async Task CreateCharacterAsync_ShouldAddCharacterToDatabase()
{
// Arrange
var characterService = _mocker.CreateInstance<CharacterService>();
var character = new PlayerCharacter { Name = "Test Character" };
// Act
await characterService.CreateCharacterAsync(character.Name, CharacterClass.Warrior, Race.Human);
var collection = _mongoDbFixture.Database.GetCollection<Character>("Characters");
var characterFromDb = await collection.Find(c => c.Name == "Test Character").FirstOrDefaultAsync();
// Assert
Assert.NotNull(characterFromDb);
Assert.Equal(character.Name, characterFromDb.Name);
}
}
-
Run Tests:
- Open the Test Explorer window from the View > Test Explorer menu.
- Click the Run All button to execute all tests.
-
View Code Coverage:
- Go to Test > Analyze Code Coverage > All Tests.
- This will display the code coverage results in the Code Coverage Results window.
- Review the results to understand the percentage of code covered by your tests.
-
Generate a Detailed Report (Optional):
- For more detailed coverage reports, you can use command-line tools as described in the previous section.
- Folder Structure: Organize your test classes into folders by feature or service to improve maintainability and clarity. Right-click on the project, choose Add > New Folder, and categorize tests accordingly.
-
Naming Conventions: Use descriptive names for test methods to clearly indicate what they are testing, such as
MethodName_StateUnderTest_ExpectedBehavior
.
- Arrange-Act-Assert Pattern: Follow this pattern consistently across all test methods to ensure clarity and maintainability.
- Mock Only What You Need: Use Moq to mock only the dependencies required for the test. Avoid over-mocking, which can make tests brittle and difficult to maintain.
- Use AutoMocker Sparingly: While Moq.AutoMock simplifies mocking setup, be mindful of its use to avoid hiding dependencies that should be explicitly declared.
Setting up a testing environment with xUnit, Moq, Moq.AutoMock, Coverlet, and Mongo2Go on .NET 8.0 provides a comprehensive foundation for testing Web APIs and MongoDB-dependent services. This environment supports high code coverage and ensures your codebase remains robust, maintainable, and reliable. By following the steps outlined in this specification, both through command-line instructions and using Visual Studio 2022 UI, you'll be well-equipped to build effective unit tests and maintain a high level of code quality throughout your development process.