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
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy