Skip to content

Commit 5ad5c76

Browse files
author
Bart Koelman
committed
Fixed broken tests; simpler bootstrap setup
1 parent cb983b9 commit 5ad5c76

File tree

5 files changed

+162
-150
lines changed

5 files changed

+162
-150
lines changed

test/MultiDbContextTests/ResourceTests.cs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace MultiDbContextTests
1313
{
14-
public sealed class ResourceTests : IClassFixture<WebApplicationFactory<Startup>>
14+
public sealed class ResourceTests : IntegrationTest, IClassFixture<WebApplicationFactory<Startup>>
1515
{
1616
private readonly WebApplicationFactory<Startup> _factory;
1717

@@ -24,42 +24,37 @@ public ResourceTests(WebApplicationFactory<Startup> factory)
2424
public async Task Can_get_ResourceAs()
2525
{
2626
// Arrange
27-
var client = _factory.CreateClient();
28-
29-
var request = new HttpRequestMessage(HttpMethod.Get, "/resourceAs");
27+
var route = "/resourceAs";
3028

3129
// Act
32-
var response = await client.SendAsync(request);
30+
var (httpResponse, responseDocument) = await ExecuteGetAsync<Document>(route);
3331

3432
// Assert
35-
response.Should().HaveStatusCode(HttpStatusCode.OK);
36-
37-
string responseBody = await response.Content.ReadAsStringAsync();
38-
var document = JsonConvert.DeserializeObject<Document>(responseBody);
33+
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
3934

40-
document.ManyData.Should().HaveCount(1);
41-
document.ManyData[0].Attributes["nameA"].Should().Be("SampleA");
35+
responseDocument.ManyData.Should().HaveCount(1);
36+
responseDocument.ManyData[0].Attributes["nameA"].Should().Be("SampleA");
4237
}
4338

4439
[Fact]
4540
public async Task Can_get_ResourceBs()
4641
{
4742
// Arrange
48-
var client = _factory.CreateClient();
49-
50-
var request = new HttpRequestMessage(HttpMethod.Get, "/resourceBs");
43+
var route = "/resourceBs";
5144

5245
// Act
53-
var response = await client.SendAsync(request);
46+
var (httpResponse, responseDocument) = await ExecuteGetAsync<Document>(route);
5447

5548
// Assert
56-
response.Should().HaveStatusCode(HttpStatusCode.OK);
49+
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
5750

58-
string responseBody = await response.Content.ReadAsStringAsync();
59-
var document = JsonConvert.DeserializeObject<Document>(responseBody);
51+
responseDocument.ManyData.Should().HaveCount(1);
52+
responseDocument.ManyData[0].Attributes["nameB"].Should().Be("SampleB");
53+
}
6054

61-
document.ManyData.Should().HaveCount(1);
62-
document.ManyData[0].Attributes["nameB"].Should().Be("SampleB");
55+
protected override HttpClient CreateClient()
56+
{
57+
return _factory.CreateClient();
6358
}
6459
}
6560
}

test/NoEntityFrameworkTests/WorkItemTests.cs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
using System;
22
using System.Net;
3+
using System.Net.Http;
34
using System.Threading.Tasks;
45
using FluentAssertions;
56
using JsonApiDotNetCore.Serialization.Objects;
7+
using Microsoft.AspNetCore.Mvc.Testing;
8+
using Microsoft.Extensions.DependencyInjection;
69
using NoEntityFrameworkExample;
710
using NoEntityFrameworkExample.Data;
811
using NoEntityFrameworkExample.Models;
@@ -11,20 +14,20 @@
1114

1215
namespace NoEntityFrameworkTests
1316
{
14-
public sealed class WorkItemTests : IClassFixture<RemoteIntegrationTestContext<Startup, AppDbContext>>
17+
public sealed class WorkItemTests : IntegrationTest, IClassFixture<WebApplicationFactory<Startup>>
1518
{
16-
private readonly RemoteIntegrationTestContext<Startup, AppDbContext> _testContext;
19+
private readonly WebApplicationFactory<Startup> _factory;
1720

18-
public WorkItemTests(RemoteIntegrationTestContext<Startup, AppDbContext> testContext)
21+
public WorkItemTests(WebApplicationFactory<Startup> factory)
1922
{
20-
_testContext = testContext;
23+
_factory = factory;
2124
}
2225

2326
[Fact]
2427
public async Task Can_get_WorkItems()
2528
{
2629
// Arrange
27-
await _testContext.RunOnDatabaseAsync(async dbContext =>
30+
await RunOnDatabaseAsync(async dbContext =>
2831
{
2932
dbContext.WorkItems.Add(new WorkItem());
3033
await dbContext.SaveChangesAsync();
@@ -33,7 +36,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
3336
var route = "/api/v1/workItems";
3437

3538
// Act
36-
var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync<Document>(route);
39+
var (httpResponse, responseDocument) = await ExecuteGetAsync<Document>(route);
3740

3841
// Assert
3942
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
@@ -47,7 +50,7 @@ public async Task Can_get_WorkItem_by_ID()
4750
// Arrange
4851
var workItem = new WorkItem();
4952

50-
await _testContext.RunOnDatabaseAsync(async dbContext =>
53+
await RunOnDatabaseAsync(async dbContext =>
5154
{
5255
dbContext.WorkItems.Add(workItem);
5356
await dbContext.SaveChangesAsync();
@@ -56,7 +59,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
5659
var route = "/api/v1/workItems/" + workItem.StringId;
5760

5861
// Act
59-
var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync<Document>(route);
62+
var (httpResponse, responseDocument) = await ExecuteGetAsync<Document>(route);
6063

6164
// Assert
6265
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
@@ -87,7 +90,7 @@ public async Task Can_create_WorkItem()
8790
var route = "/api/v1/workItems/";
8891

8992
// Act
90-
var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync<Document>(route, requestBody);
93+
var (httpResponse, responseDocument) = await ExecutePostAsync<Document>(route, requestBody);
9194

9295
// Assert
9396
httpResponse.Should().HaveStatusCode(HttpStatusCode.Created);
@@ -102,7 +105,7 @@ public async Task Can_delete_WorkItem()
102105
// Arrange
103106
var workItem = new WorkItem();
104107

105-
await _testContext.RunOnDatabaseAsync(async dbContext =>
108+
await RunOnDatabaseAsync(async dbContext =>
106109
{
107110
dbContext.WorkItems.Add(workItem);
108111
await dbContext.SaveChangesAsync();
@@ -111,12 +114,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
111114
var route = "/api/v1/workItems/" + workItem.StringId;
112115

113116
// Act
114-
var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync<string>(route);
117+
var (httpResponse, responseDocument) = await ExecuteDeleteAsync<string>(route);
115118

116119
// Assert
117120
httpResponse.Should().HaveStatusCode(HttpStatusCode.NoContent);
118121

119122
responseDocument.Should().BeEmpty();
120123
}
124+
125+
protected override HttpClient CreateClient()
126+
{
127+
return _factory.CreateClient();
128+
}
129+
130+
private async Task RunOnDatabaseAsync(Func<AppDbContext, Task> asyncAction)
131+
{
132+
using IServiceScope scope = _factory.Services.CreateScope();
133+
var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
134+
135+
await asyncAction(dbContext);
136+
}
121137
}
122138
}

test/TestBuildingBlocks/BaseIntegrationTestContext.cs

Lines changed: 6 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Net.Http;
4-
using System.Net.Http.Headers;
53
using System.Threading.Tasks;
6-
using JsonApiDotNetCore.Middleware;
74
using Microsoft.AspNetCore.Hosting;
85
using Microsoft.AspNetCore.Mvc.Testing;
96
using Microsoft.EntityFrameworkCore;
107
using Microsoft.Extensions.DependencyInjection;
118
using Microsoft.Extensions.Hosting;
129
using Microsoft.Extensions.Logging;
13-
using Newtonsoft.Json;
1410

1511
namespace TestBuildingBlocks
1612
{
@@ -23,7 +19,7 @@ namespace TestBuildingBlocks
2319
/// <typeparam name="TStartup">The server Startup class, which can be defined in the test project.</typeparam>
2420
/// <typeparam name="TRemoteStartup">The base class for <typeparamref name="TStartup"/>, which MUST be defined in the API project.</typeparam>
2521
/// <typeparam name="TDbContext">The EF Core database context, which can be defined in the test project.</typeparam>
26-
public abstract class BaseIntegrationTestContext<TStartup, TRemoteStartup, TDbContext> : IDisposable
22+
public abstract class BaseIntegrationTestContext<TStartup, TRemoteStartup, TDbContext> : IntegrationTest, IDisposable
2723
where TStartup : class
2824
where TRemoteStartup : class
2925
where TDbContext : DbContext
@@ -35,6 +31,11 @@ public abstract class BaseIntegrationTestContext<TStartup, TRemoteStartup, TDbCo
3531

3632
public WebApplicationFactory<TRemoteStartup> Factory => _lazyFactory.Value;
3733

34+
protected override HttpClient CreateClient()
35+
{
36+
return Factory.CreateClient();
37+
}
38+
3839
protected BaseIntegrationTestContext()
3940
{
4041
_lazyFactory = new Lazy<WebApplicationFactory<TRemoteStartup>>(CreateFactory);
@@ -103,102 +104,6 @@ public async Task RunOnDatabaseAsync(Func<TDbContext, Task> asyncAction)
103104
await asyncAction(dbContext);
104105
}
105106

106-
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
107-
ExecuteGetAsync<TResponseDocument>(string requestUrl,
108-
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders = null)
109-
{
110-
return await ExecuteRequestAsync<TResponseDocument>(HttpMethod.Get, requestUrl, null, null, acceptHeaders);
111-
}
112-
113-
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
114-
ExecutePostAsync<TResponseDocument>(string requestUrl, object requestBody,
115-
string contentType = HeaderConstants.MediaType,
116-
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders = null)
117-
{
118-
return await ExecuteRequestAsync<TResponseDocument>(HttpMethod.Post, requestUrl, requestBody, contentType,
119-
acceptHeaders);
120-
}
121-
122-
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
123-
ExecutePatchAsync<TResponseDocument>(string requestUrl, object requestBody,
124-
string contentType = HeaderConstants.MediaType,
125-
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders = null)
126-
{
127-
return await ExecuteRequestAsync<TResponseDocument>(HttpMethod.Patch, requestUrl, requestBody, contentType,
128-
acceptHeaders);
129-
}
130-
131-
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
132-
ExecuteDeleteAsync<TResponseDocument>(string requestUrl, object requestBody = null,
133-
string contentType = HeaderConstants.MediaType,
134-
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders = null)
135-
{
136-
return await ExecuteRequestAsync<TResponseDocument>(HttpMethod.Delete, requestUrl, requestBody, contentType,
137-
acceptHeaders);
138-
}
139-
140-
private async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
141-
ExecuteRequestAsync<TResponseDocument>(HttpMethod method, string requestUrl, object requestBody,
142-
string contentType, IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders)
143-
{
144-
var request = new HttpRequestMessage(method, requestUrl);
145-
string requestText = SerializeRequest(requestBody);
146-
147-
if (!string.IsNullOrEmpty(requestText))
148-
{
149-
request.Content = new StringContent(requestText);
150-
151-
if (contentType != null)
152-
{
153-
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
154-
}
155-
}
156-
157-
using HttpClient client = Factory.CreateClient();
158-
159-
if (acceptHeaders != null)
160-
{
161-
foreach (var acceptHeader in acceptHeaders)
162-
{
163-
client.DefaultRequestHeaders.Accept.Add(acceptHeader);
164-
}
165-
}
166-
167-
HttpResponseMessage responseMessage = await client.SendAsync(request);
168-
169-
string responseText = await responseMessage.Content.ReadAsStringAsync();
170-
var responseDocument = DeserializeResponse<TResponseDocument>(responseText);
171-
172-
return (responseMessage, responseDocument);
173-
}
174-
175-
private string SerializeRequest(object requestBody)
176-
{
177-
return requestBody == null
178-
? null
179-
: requestBody is string stringRequestBody
180-
? stringRequestBody
181-
: JsonConvert.SerializeObject(requestBody);
182-
}
183-
184-
private TResponseDocument DeserializeResponse<TResponseDocument>(string responseText)
185-
{
186-
if (typeof(TResponseDocument) == typeof(string))
187-
{
188-
return (TResponseDocument)(object)responseText;
189-
}
190-
191-
try
192-
{
193-
return JsonConvert.DeserializeObject<TResponseDocument>(responseText,
194-
IntegrationTestConfiguration.DeserializationSettings);
195-
}
196-
catch (JsonException exception)
197-
{
198-
throw new FormatException($"Failed to deserialize response body to JSON:\n{responseText}", exception);
199-
}
200-
}
201-
202107
private sealed class IntegrationTestWebApplicationFactory : WebApplicationFactory<TRemoteStartup>
203108
{
204109
private Action<ILoggingBuilder> _loggingConfiguration;

0 commit comments

Comments
 (0)