Add basic unit tests

This commit is contained in:
Alex Hyett 2023-07-05 11:32:03 +01:00
parent ad6e0d2015
commit b30304a291
7 changed files with 216 additions and 1 deletions

33
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,33 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/GitHubActionsDemo.Api/bin/Debug/net7.0/GitHubActionsDemo.Api.dll",
"args": [],
"cwd": "${workspaceFolder}/src/GitHubActionsDemo.Api",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

62
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,62 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/GitHubActionsDemo.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/GitHubActionsDemo.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/GitHubActionsDemo.sln"
],
"problemMatcher": "$msCompile"
},
{
"label": ".NET Core Test with debugger",
"type": "process",
"isBackground": true,
"command": "dotnet",
"args": ["test"],
"options": {
"cwd": "${workspaceFolder}/tests",
"env": {
"VSTEST_HOST_DEBUG": "1"
}
},
"group": "test",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"problemMatcher": []
}
]
}

View file

@ -11,6 +11,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Service",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Persistance", "src\GitHubActionsDemo.Persistance\GitHubActionsDemo.Persistance.csproj", "{339301B3-E9BD-45D1-B6A9-94F41367DF16}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{015E0E24-CD73-48C7-8565-5A566F5DAB87}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Api.Tests", "test\GitHubActionsDemo.Api.Tests\GitHubActionsDemo.Api.Tests.csproj", "{AA6299AC-C10C-49CD-89A3-33122123AE7A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -32,10 +36,15 @@ Global
{339301B3-E9BD-45D1-B6A9-94F41367DF16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{339301B3-E9BD-45D1-B6A9-94F41367DF16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{339301B3-E9BD-45D1-B6A9-94F41367DF16}.Release|Any CPU.Build.0 = Release|Any CPU
{AA6299AC-C10C-49CD-89A3-33122123AE7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA6299AC-C10C-49CD-89A3-33122123AE7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA6299AC-C10C-49CD-89A3-33122123AE7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA6299AC-C10C-49CD-89A3-33122123AE7A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E3C34F79-B74E-44A4-99F0-B0B3C2D7CCB2} = {53A44CCA-C5C6-4D98-91B8-D331D68BF7B0}
{F6807FFB-3C0D-4F84-8803-8ECAFD72EF76} = {53A44CCA-C5C6-4D98-91B8-D331D68BF7B0}
{339301B3-E9BD-45D1-B6A9-94F41367DF16} = {53A44CCA-C5C6-4D98-91B8-D331D68BF7B0}
{AA6299AC-C10C-49CD-89A3-33122123AE7A} = {015E0E24-CD73-48C7-8565-5A566F5DAB87}
EndGlobalSection
EndGlobal

View file

@ -1,4 +1,3 @@
using System.Runtime.Intrinsics.X86;
using GitHubActionsDemo.Api.Models;
using GitHubActionsDemo.Api.Mappers;
using GitHubActionsDemo.Service;

View file

@ -0,0 +1,80 @@
using System.Net;
using FluentValidation;
using FluentValidation.Results;
using GitHubActionsDemo.Api.Controllers;
using GitHubActionsDemo.Api.Models;
using GitHubActionsDemo.Service;
using GitHubActionsDemo.Service.Models;
using Microsoft.AspNetCore.Http.HttpResults;
using Moq;
using Shouldly;
namespace GitHubActionsDemo.Api.Tests;
public class AuthorsControllerTests
{
private readonly Mock<ILibraryService> _libraryService;
private readonly Mock<IValidator<AuthorRequest>> _authorValidator;
private readonly Mock<IValidator<PageParameters>> _pageValidator;
private readonly AuthorsController _sut;
public AuthorsControllerTests()
{
_libraryService = new Mock<ILibraryService>();
_authorValidator = new Mock<IValidator<AuthorRequest>>();
_pageValidator = new Mock<IValidator<PageParameters>>();
_sut = new AuthorsController(_libraryService.Object, _authorValidator.Object, _pageValidator.Object);
}
[Fact]
public async Task Given_invalid_request_should_return_validation_problem()
{
var request = new AuthorRequest
{
FirstName = "",
LastName = ""
};
var failures = new List<ValidationFailure>
{
new ValidationFailure("FirstName", "Missing"),
new ValidationFailure("LastName", "Missing")
};
_authorValidator.Setup(x => x.ValidateAsync(request, It.IsAny<CancellationToken>()))
.ReturnsAsync(new ValidationResult(failures));
var result = await _sut.AddAuthorAsync(request);
var problem = result as ProblemHttpResult;
problem.ShouldNotBeNull();
}
[Fact]
public async Task Given_valid_request_should_return_author()
{
var request = new AuthorRequest
{
FirstName = "Joe",
LastName = "Bloggs"
};
var mockAuthor = new Author(1, request.FirstName, request.LastName, DateTime.UtcNow, DateTime.UtcNow);
_authorValidator.Setup(x => x.ValidateAsync(request, It.IsAny<CancellationToken>()))
.ReturnsAsync(new ValidationResult());
_libraryService.Setup(
x => x.AddAuthorAsync(It.Is<NewAuthor>(a =>
a.FirstName == request.FirstName &&
a.LastName == request.LastName)))
.ReturnsAsync(new OneOf.Types.Success<Author>(mockAuthor));
var result = await _sut.AddAuthorAsync(request);
var successValue = result as Ok<AuthorResponse>;
successValue.ShouldNotBeNull();
successValue.StatusCode.ShouldBe((int)HttpStatusCode.OK);
successValue.Value.FirstName.ShouldBe(request.FirstName);
successValue.Value.LastName.ShouldBe(request.LastName);
}
}

View file

@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="Shouldly" Version="4.2.1" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\GitHubActionsDemo.Api\GitHubActionsDemo.Api.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1 @@
global using Xunit;