Skip to content

Commit 0ece8a4

Browse files
authored
Introduce an example integration test around HomeController (#8)
Introduce an example integration test around HomeController.
1 parent fbc5b03 commit 0ece8a4

3 files changed

Lines changed: 121 additions & 1 deletion

File tree

Directory.Packages.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
</PropertyGroup>
66
<ItemGroup>
77
<!-- Static code analysis -->
8+
<PackageVersion Include="AngleSharp" Version="1.6.0" />
89
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.10" />
910
<PackageVersion Include="NSubstitute" Version="6.0.0" />
1011
<PackageVersion Include="SonarAnalyzer.CSharp" Version="10.30.0.144632" />
@@ -31,4 +32,4 @@
3132
<PackageVersion Include="Microsoft.Testing.Extensions.GitHubActionsReport" Version="1.0.0-alpha.26377.5" />
3233
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="2.3.3" />
3334
</ItemGroup>
34-
</Project>
35+
</Project>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using System.Net;
2+
using AngleSharp;
3+
using AngleSharp.Dom;
4+
using Microsoft.AspNetCore.Mvc.Testing;
5+
using Microsoft.AspNetCore.TestHost;
6+
using NSubstitute;
7+
using NSubstitute.ExceptionExtensions;
8+
using SchoolAccount.Application.Abstractions.Messaging;
9+
using SchoolAccount.Application.Greetings.GetTimeSpecificHello;
10+
using SchoolAccount.SharedKernel;
11+
using Shouldly;
12+
13+
namespace SchoolAccount.IntegrationTests.Controllers.Home;
14+
15+
public class HomeControllerTests : IClassFixture<WebApplicationFactory<Program>>
16+
{
17+
private readonly HttpClient _client;
18+
private readonly IQueryHandler<
19+
GetTimeSpecificHelloQuery,
20+
GetTimeSpecificHelloResponse
21+
> _getTimeSpecificHelloHandler = Substitute.For<
22+
IQueryHandler<GetTimeSpecificHelloQuery, GetTimeSpecificHelloResponse>
23+
>();
24+
25+
public HomeControllerTests(WebApplicationFactory<Program> factory)
26+
{
27+
_client = factory
28+
.WithWebHostBuilder(builder =>
29+
builder.ConfigureTestServices(services =>
30+
services.AddScoped<
31+
IQueryHandler<GetTimeSpecificHelloQuery, GetTimeSpecificHelloResponse>
32+
>(_ => _getTimeSpecificHelloHandler)
33+
)
34+
)
35+
.CreateClient();
36+
}
37+
38+
[Fact]
39+
public async Task Ensure_that_the_home_controller_returns_a_successful_result()
40+
{
41+
// Arrange
42+
var stubbedGetSpecificHelloResponse = new GetTimeSpecificHelloResponse(
43+
GetTimeSpecificHelloHandler.Messages.Morning
44+
);
45+
_getTimeSpecificHelloHandler
46+
.Handle(Arg.Any<GetTimeSpecificHelloQuery>(), Arg.Any<CancellationToken>())
47+
.Returns(Result.Success(stubbedGetSpecificHelloResponse));
48+
49+
// Act
50+
HttpResponseMessage response = await _client.GetAsync(
51+
"/",
52+
TestContext.Current.CancellationToken
53+
);
54+
55+
// Assert
56+
response.IsSuccessStatusCode.ShouldBeTrue();
57+
58+
string html = await response.Content.ReadAsStringAsync(
59+
TestContext.Current.CancellationToken
60+
);
61+
IBrowsingContext context = BrowsingContext.New(Configuration.Default);
62+
IDocument page = await context.OpenAsync(
63+
req => req.Content(html),
64+
TestContext.Current.CancellationToken
65+
);
66+
67+
page.ShouldNotBeNull();
68+
69+
IElement? pageTitle = page.QuerySelector("title");
70+
pageTitle.ShouldNotBeNull();
71+
pageTitle.TextContent.ShouldBeEquivalentTo("Home Page");
72+
73+
IElement? headingElement = page.QuerySelector("h1.govuk-heading-l");
74+
headingElement.ShouldNotBeNull();
75+
headingElement.TextContent.ShouldBeEquivalentTo(stubbedGetSpecificHelloResponse.Message);
76+
77+
IElement? bodyElement = page.QuerySelector("p.govuk-body");
78+
bodyElement.ShouldNotBeNull();
79+
bodyElement.TextContent.ShouldContainWithoutWhitespace("In case I don't see ya");
80+
}
81+
82+
[Fact]
83+
public async Task Ensure_that_the_home_controller_returns_a_404_result_on_unknown_page()
84+
{
85+
// Act
86+
HttpResponseMessage response = await _client.GetAsync(
87+
"/orangesandapples",
88+
TestContext.Current.CancellationToken
89+
);
90+
91+
// Assert
92+
response.IsSuccessStatusCode.ShouldBeFalse();
93+
response.StatusCode.ShouldBe(HttpStatusCode.NotFound);
94+
}
95+
96+
[Fact]
97+
public async Task Ensure_that_when_the_home_controller_fails_it_returns_a_500_result()
98+
{
99+
// Arrange
100+
_getTimeSpecificHelloHandler
101+
.Handle(Arg.Any<GetTimeSpecificHelloQuery>(), Arg.Any<CancellationToken>())
102+
.Throws(new ApplicationException("Bang!"));
103+
104+
// Act
105+
HttpResponseMessage response = await _client.GetAsync(
106+
"/",
107+
TestContext.Current.CancellationToken
108+
);
109+
110+
// Assert
111+
response.IsSuccessStatusCode.ShouldBeFalse();
112+
response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
113+
}
114+
}

tests/SchoolAccount.IntegrationTests/SchoolAccount.IntegrationTests.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11+
<PackageReference Include="AngleSharp" />
1112
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
1213
<PackageReference Include="NSubstitute" />
1314
<PackageReference Include="Shouldly" />
@@ -20,4 +21,8 @@
2021
<ItemGroup>
2122
<Using Include="Xunit" />
2223
</ItemGroup>
24+
25+
<ItemGroup>
26+
<ProjectReference Include="..\..\src\SchoolAccount.Web.Mvc\SchoolAccount.Web.Mvc.csproj" />
27+
</ItemGroup>
2328
</Project>

0 commit comments

Comments
 (0)