Skip to content

dimitrietataru/csharp-unit-testing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

80 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C# Unit Testing

Coverage

Table of contents

NuGet packages

PM> Install-Package Bogus -Version 32.0.2 PM> Install-Package coverlet.collector -Version 1.3.0 PM> Install-Package FluentAssertions -Version 5.10.3 PM> Install-Package Microsoft.NET.Test.Sdk -Version 16.8.3 PM> Install-Package Moq -Version 4.15.2 PM> Install-Package ReportGenerator -Version 4.8.1 PM> Install-Package Shouldly -Version 4.0.1 # NUnit PM> Install-Package NUnit -Version 3.12.0 PM> Install-Package NUnit3TestAdapter -Version 3.17.0 # xUnit PM> Install-Package xunit -Version 2.4.1 PM> Install-Package xunit.runner.visualstudio -Version 2.4.3

Syntax

Given-When-Then pattern

Martin Fowler's blog

Arrange-Act-Assert pattern

Docs.Microsoft

Moq setup and verify

// Setup async method when it returns data mockService .Setup(_ => _.GetAsync(It.IsAny<int>())) .ReturnsAsync(It.IsAny<Data>()) .Verifiable(); // Setup async method when it executes without a return type mockService .Setup(_ => _.RunAsync()) .ReturnsAsync(Task.CompletedTask) .Verifiable(); // Setup async method when it throws an exception mockService .Setup(_ => _.RunAsync(It.IsAny<int>())) .Throws<Exception>() .Verifiable(); // Verify all service methods, marked as 'Verifiable' mockService.VerifyAll(); // Verify individual service method mockService.Verify(_ => _.GetAsync(It.IsAny<int>()), Times.Once); mockService.Verify(_ => _.RunAsync(), Times.Exactly(2)); mockService.Verify(_ => _.RunAsync(It.IsAny<int>()), Times.Never);

Assertions

// NUnit Assert.That(result, Is.InstanceOf<ObjectResult>()); var apiResponse = result as OkObjectResult; Assert.That(apiResponse.StatusCode, Is.EqualTo((int)HttpStatusCode.OK)); // xUnit var apiResponse = Assert.IsType<OkObjectResult>(result); Assert.Equal((int)HttpStatusCode.OK, apiResponse.StatusCode); // FluentAssertions result .Should().BeOfType<OkObjectResult>("because we return content") .Which.StatusCode.Should().Be((int)HttpStatusCode.OK); // Shouldly result.ShouldSatisfyAllConditions( () => result.ShouldBeOfType<OkObjectResult>(), () => (result as OkObjectResult).StatusCode.ShouldBe((int)HttpStatusCode.OK));

Collect code coverage

Install coverlet.collector NuGet package

PM> Install-Package coverlet.collector -Version 1.3.0

TestProject.csproj configuration

<PackageReference Include="coverlet.collector" Version="1.3.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference>

Collector configuration. Add a file (e.g. runsettings) anywhere in the solution/project

<?xml version="1.0" encoding="utf-8" ?> <RunSettings> <DataCollectionRunSettings> <DataCollectors> <DataCollector friendlyName="XPlat code coverage"> <Configuration> <Format>json,cobertura</Format> <UseSourceLink>true</UseSourceLink> <IncludeTestAssembly>false</IncludeTestAssembly> <ExcludeByFile>**/**/Program.cs,**/**/Startup.cs,**/Dir/SubDir/*.cs</ExcludeByFile> </Configuration> </DataCollector> </DataCollectors> </DataCollectionRunSettings> <InProcDataCollectionRunSettings> <InProcDataCollectors> <InProcDataCollector assemblyQualifiedName="Coverlet.Collector.DataCollection.CoverletInProcDataCollector, coverlet.collector, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null" friendlyName="XPlat Code Coverage" enabled="True" codebase="coverlet.collector.dll" /> </InProcDataCollectors> </InProcDataCollectionRunSettings> </RunSettings>

Run tests and collect data

PM> dotnet test --collect:"XPlat Code Coverage" --settings .\runsettings PM> dotnet test .\Specific.Test.Project --collect:"XPlat Code Coverage" --settings .\Specific.Test.Project\runsettings

Generate Code Coverage Report

Install ReportGenerator NuGet package

PM> Install-Package ReportGenerator -Version 4.8.1

Generate reports

ReportGenerator usage page

PM> dotnet $(UserProfile)\.nuget\packages\reportgenerator\x.y.z\tools\netcoreapp3.0\ReportGenerator.dll "-reports:coverage.xml" "-targetdir:coveragereport" -reporttypes:Html PM> dotnet $(UserProfile)\.nuget\packages\reportgenerator\x.y.z\tools\netcoreapp3.0\ReportGenerator.dll "-reports:coverage.xml" "-targetdir:coveragereport" -reporttypes:Badges
# CSharp.UnitTesting.Api NUnit PM> dotnet $(UserProfile)\.nuget\packages\reportgenerator\4.8.1\tools\netcoreapp3.0\ReportGenerator.dll "-reports:CSharp.UnitTesting.Api.Nunit.Test\TestResults\*\coverage.cobertura.xml" "-targetdir:_CoverageReport\Api\NUnit" "-historydir:_CoverageReport\_History\Api\NUnit" -reporttypes:Html # CSharp.UnitTesting.Api xUnit PM> dotnet $(UserProfile)\.nuget\packages\reportgenerator\4.8.1\tools\netcoreapp3.0\ReportGenerator.dll "-reports:CSharp.UnitTesting.Api.Xunit.Test\TestResults\*\coverage.cobertura.xml" "-targetdir:_CoverageReport\Api\xUnit" "-historydir:_CoverageReport\_History\Api\xUnit" -reporttypes:Html