Skip to content

Commit c7000b8

Browse files
author
Bart Koelman
committed
Extracted test building blocks in shared project
1 parent 255ed36 commit c7000b8

32 files changed

+308
-319
lines changed

JsonApiDotNetCore.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiDbContextExample", "sr
4545
EndProject
4646
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiDbContextTests", "test\MultiDbContextTests\MultiDbContextTests.csproj", "{EC3202C6-1D4C-4B14-A599-B9D3F27FE3BA}"
4747
EndProject
48+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBuildingBlocks", "test\TestBuildingBlocks\TestBuildingBlocks.csproj", "{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}"
49+
EndProject
4850
Global
4951
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5052
Debug|Any CPU = Debug|Any CPU
@@ -199,6 +201,18 @@ Global
199201
{EC3202C6-1D4C-4B14-A599-B9D3F27FE3BA}.Release|x64.Build.0 = Release|Any CPU
200202
{EC3202C6-1D4C-4B14-A599-B9D3F27FE3BA}.Release|x86.ActiveCfg = Release|Any CPU
201203
{EC3202C6-1D4C-4B14-A599-B9D3F27FE3BA}.Release|x86.Build.0 = Release|Any CPU
204+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
205+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Debug|Any CPU.Build.0 = Debug|Any CPU
206+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Debug|x64.ActiveCfg = Debug|Any CPU
207+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Debug|x64.Build.0 = Debug|Any CPU
208+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Debug|x86.ActiveCfg = Debug|Any CPU
209+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Debug|x86.Build.0 = Debug|Any CPU
210+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|Any CPU.ActiveCfg = Release|Any CPU
211+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|Any CPU.Build.0 = Release|Any CPU
212+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|x64.ActiveCfg = Release|Any CPU
213+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|x64.Build.0 = Release|Any CPU
214+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|x86.ActiveCfg = Release|Any CPU
215+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|x86.Build.0 = Release|Any CPU
202216
EndGlobalSection
203217
GlobalSection(SolutionProperties) = preSolution
204218
HideSolutionNode = FALSE
@@ -216,6 +230,7 @@ Global
216230
{21D27239-138D-4604-8E49-DCBE41BCE4C8} = {7A2B7ADD-ECB5-4D00-AA6A-D45BD11C97CF}
217231
{6CAFDDBE-00AB-4784-801B-AB419C3C3A26} = {026FBC6C-AF76-4568-9B87-EC73457899FD}
218232
{EC3202C6-1D4C-4B14-A599-B9D3F27FE3BA} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
233+
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
219234
EndGlobalSection
220235
GlobalSection(ExtensibilityGlobals) = postSolution
221236
SolutionGuid = {A2421882-8F0A-4905-928F-B550B192F9A4}

test/DiscoveryTests/DiscoveryTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
<ItemGroup>
1313
<ProjectReference Include="..\..\src\Examples\JsonApiDotNetCoreExample\JsonApiDotNetCoreExample.csproj" />
14+
<ProjectReference Include="..\TestBuildingBlocks\TestBuildingBlocks.csproj" />
1415
</ItemGroup>
1516

1617
<ItemGroup>
1718
<PackageReference Include="Moq" Version="$(MoqVersion)" />
18-
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
1919
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
2020
</ItemGroup>
2121
</Project>

test/JsonApiDotNetCoreExampleTests/ExampleFakers.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using Bogus;
33
using JsonApiDotNetCoreExample.Data;
44
using JsonApiDotNetCoreExample.Models;
5-
using JsonApiDotNetCoreExampleTests.IntegrationTests;
65
using Microsoft.Extensions.DependencyInjection;
76
using Person = JsonApiDotNetCoreExample.Models.Person;
87

Lines changed: 1 addition & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Net.Http;
4-
using System.Net.Http.Headers;
5-
using System.Threading.Tasks;
6-
using JsonApiDotNetCore.Middleware;
71
using JsonApiDotNetCoreExample;
8-
using Microsoft.AspNetCore.Hosting;
9-
using Microsoft.AspNetCore.Mvc.Testing;
102
using Microsoft.EntityFrameworkCore;
11-
using Microsoft.Extensions.DependencyInjection;
12-
using Microsoft.Extensions.Hosting;
13-
using Microsoft.Extensions.Logging;
14-
using Newtonsoft.Json;
153

164
namespace JsonApiDotNetCoreExampleTests
175
{
@@ -23,225 +11,9 @@ namespace JsonApiDotNetCoreExampleTests
2311
/// </summary>
2412
/// <typeparam name="TStartup">The server Startup class, which can be defined in the test project.</typeparam>
2513
/// <typeparam name="TDbContext">The EF Core database context, which can be defined in the test project.</typeparam>
26-
public class IntegrationTestContext<TStartup, TDbContext> : IDisposable
14+
public class IntegrationTestContext<TStartup, TDbContext> : BaseIntegrationTestContext<TStartup, EmptyStartup, TDbContext>
2715
where TStartup : class
2816
where TDbContext : DbContext
2917
{
30-
private readonly Lazy<WebApplicationFactory<EmptyStartup>> _lazyFactory;
31-
private Action<ILoggingBuilder> _loggingConfiguration;
32-
private Action<IServiceCollection> _beforeServicesConfiguration;
33-
private Action<IServiceCollection> _afterServicesConfiguration;
34-
35-
public WebApplicationFactory<EmptyStartup> Factory => _lazyFactory.Value;
36-
37-
public IntegrationTestContext()
38-
{
39-
_lazyFactory = new Lazy<WebApplicationFactory<EmptyStartup>>(CreateFactory);
40-
}
41-
42-
private WebApplicationFactory<EmptyStartup> CreateFactory()
43-
{
44-
string postgresPassword = Environment.GetEnvironmentVariable("PGPASSWORD") ?? "postgres";
45-
string dbConnectionString =
46-
$"Host=localhost;Port=5432;Database=JsonApiTest-{Guid.NewGuid():N};User ID=postgres;Password={postgresPassword}";
47-
48-
var factory = new IntegrationTestWebApplicationFactory();
49-
50-
factory.ConfigureLogging(_loggingConfiguration);
51-
52-
factory.ConfigureServicesBeforeStartup(services =>
53-
{
54-
_beforeServicesConfiguration?.Invoke(services);
55-
56-
services.AddDbContext<TDbContext>(options =>
57-
{
58-
options.UseNpgsql(dbConnectionString,
59-
postgresOptions => postgresOptions.SetPostgresVersion(new Version(9, 6)));
60-
61-
options.EnableSensitiveDataLogging();
62-
options.EnableDetailedErrors();
63-
});
64-
});
65-
66-
factory.ConfigureServicesAfterStartup(_afterServicesConfiguration);
67-
68-
using IServiceScope scope = factory.Services.CreateScope();
69-
var dbContext = scope.ServiceProvider.GetRequiredService<TDbContext>();
70-
dbContext.Database.EnsureCreated();
71-
72-
return factory;
73-
}
74-
75-
public void Dispose()
76-
{
77-
RunOnDatabaseAsync(async context => await context.Database.EnsureDeletedAsync()).Wait();
78-
79-
Factory.Dispose();
80-
}
81-
82-
public void ConfigureLogging(Action<ILoggingBuilder> loggingConfiguration)
83-
{
84-
_loggingConfiguration = loggingConfiguration;
85-
}
86-
87-
public void ConfigureServicesBeforeStartup(Action<IServiceCollection> servicesConfiguration)
88-
{
89-
_beforeServicesConfiguration = servicesConfiguration;
90-
}
91-
92-
public void ConfigureServicesAfterStartup(Action<IServiceCollection> servicesConfiguration)
93-
{
94-
_afterServicesConfiguration = servicesConfiguration;
95-
}
96-
97-
public async Task RunOnDatabaseAsync(Func<TDbContext, Task> asyncAction)
98-
{
99-
using IServiceScope scope = Factory.Services.CreateScope();
100-
var dbContext = scope.ServiceProvider.GetRequiredService<TDbContext>();
101-
102-
await asyncAction(dbContext);
103-
}
104-
105-
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
106-
ExecuteGetAsync<TResponseDocument>(string requestUrl,
107-
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders = null)
108-
{
109-
return await ExecuteRequestAsync<TResponseDocument>(HttpMethod.Get, requestUrl, null, null, acceptHeaders);
110-
}
111-
112-
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
113-
ExecutePostAsync<TResponseDocument>(string requestUrl, object requestBody,
114-
string contentType = HeaderConstants.MediaType,
115-
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders = null)
116-
{
117-
return await ExecuteRequestAsync<TResponseDocument>(HttpMethod.Post, requestUrl, requestBody, contentType,
118-
acceptHeaders);
119-
}
120-
121-
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
122-
ExecutePatchAsync<TResponseDocument>(string requestUrl, object requestBody,
123-
string contentType = HeaderConstants.MediaType,
124-
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders = null)
125-
{
126-
return await ExecuteRequestAsync<TResponseDocument>(HttpMethod.Patch, requestUrl, requestBody, contentType,
127-
acceptHeaders);
128-
}
129-
130-
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
131-
ExecuteDeleteAsync<TResponseDocument>(string requestUrl, object requestBody = null,
132-
string contentType = HeaderConstants.MediaType,
133-
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders = null)
134-
{
135-
return await ExecuteRequestAsync<TResponseDocument>(HttpMethod.Delete, requestUrl, requestBody, contentType,
136-
acceptHeaders);
137-
}
138-
139-
private async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)>
140-
ExecuteRequestAsync<TResponseDocument>(HttpMethod method, string requestUrl, object requestBody,
141-
string contentType, IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaders)
142-
{
143-
var request = new HttpRequestMessage(method, requestUrl);
144-
string requestText = SerializeRequest(requestBody);
145-
146-
if (!string.IsNullOrEmpty(requestText))
147-
{
148-
request.Content = new StringContent(requestText);
149-
150-
if (contentType != null)
151-
{
152-
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
153-
}
154-
}
155-
156-
using HttpClient client = Factory.CreateClient();
157-
158-
if (acceptHeaders != null)
159-
{
160-
foreach (var acceptHeader in acceptHeaders)
161-
{
162-
client.DefaultRequestHeaders.Accept.Add(acceptHeader);
163-
}
164-
}
165-
166-
HttpResponseMessage responseMessage = await client.SendAsync(request);
167-
168-
string responseText = await responseMessage.Content.ReadAsStringAsync();
169-
var responseDocument = DeserializeResponse<TResponseDocument>(responseText);
170-
171-
return (responseMessage, responseDocument);
172-
}
173-
174-
private string SerializeRequest(object requestBody)
175-
{
176-
return requestBody == null
177-
? null
178-
: requestBody is string stringRequestBody
179-
? stringRequestBody
180-
: JsonConvert.SerializeObject(requestBody);
181-
}
182-
183-
private TResponseDocument DeserializeResponse<TResponseDocument>(string responseText)
184-
{
185-
if (typeof(TResponseDocument) == typeof(string))
186-
{
187-
return (TResponseDocument)(object)responseText;
188-
}
189-
190-
try
191-
{
192-
return JsonConvert.DeserializeObject<TResponseDocument>(responseText,
193-
IntegrationTestConfiguration.DeserializationSettings);
194-
}
195-
catch (JsonException exception)
196-
{
197-
throw new FormatException($"Failed to deserialize response body to JSON:\n{responseText}", exception);
198-
}
199-
}
200-
201-
private sealed class IntegrationTestWebApplicationFactory : WebApplicationFactory<EmptyStartup>
202-
{
203-
private Action<ILoggingBuilder> _loggingConfiguration;
204-
private Action<IServiceCollection> _beforeServicesConfiguration;
205-
private Action<IServiceCollection> _afterServicesConfiguration;
206-
207-
public void ConfigureLogging(Action<ILoggingBuilder> loggingConfiguration)
208-
{
209-
_loggingConfiguration = loggingConfiguration;
210-
}
211-
212-
public void ConfigureServicesBeforeStartup(Action<IServiceCollection> servicesConfiguration)
213-
{
214-
_beforeServicesConfiguration = servicesConfiguration;
215-
}
216-
217-
public void ConfigureServicesAfterStartup(Action<IServiceCollection> servicesConfiguration)
218-
{
219-
_afterServicesConfiguration = servicesConfiguration;
220-
}
221-
222-
protected override IHostBuilder CreateHostBuilder()
223-
{
224-
return Host.CreateDefaultBuilder(null)
225-
.ConfigureWebHostDefaults(webBuilder =>
226-
{
227-
webBuilder.ConfigureLogging(options =>
228-
{
229-
_loggingConfiguration?.Invoke(options);
230-
});
231-
232-
webBuilder.ConfigureServices(services =>
233-
{
234-
_beforeServicesConfiguration?.Invoke(services);
235-
});
236-
237-
webBuilder.UseStartup<TStartup>();
238-
239-
webBuilder.ConfigureServices(services =>
240-
{
241-
_afterServicesConfiguration?.Invoke(services);
242-
});
243-
});
244-
}
245-
}
24618
}
24719
}

test/JsonApiDotNetCoreExampleTests/JsonApiDotNetCoreExampleTests.csproj

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@
1111

1212
<ItemGroup>
1313
<ProjectReference Include="..\..\src\Examples\JsonApiDotNetCoreExample\JsonApiDotNetCoreExample.csproj" />
14+
<ProjectReference Include="..\TestBuildingBlocks\TestBuildingBlocks.csproj" />
1415
</ItemGroup>
1516

1617
<ItemGroup>
17-
<PackageReference Include="Bogus" Version="$(BogusVersion)" />
18-
<PackageReference Include="FluentAssertions" Version="$(FluentAssertionsVersion)" />
1918
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(AspNetCoreVersion)" />
20-
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
2119
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
2220
</ItemGroup>
2321
</Project>

test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using JsonApiDotNetCore.Configuration;
2-
using JsonApiDotNetCoreExampleTests.IntegrationTests;
32
using Microsoft.EntityFrameworkCore;
43
using Microsoft.Extensions.Configuration;
54

test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using JsonApiDotNetCore.Configuration;
2-
using JsonApiDotNetCoreExampleTests.IntegrationTests;
32
using Microsoft.EntityFrameworkCore;
43
using Microsoft.Extensions.Configuration;
54

test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using JsonApiDotNetCore.Configuration;
2-
using JsonApiDotNetCoreExampleTests.IntegrationTests;
32
using Microsoft.EntityFrameworkCore;
43
using Microsoft.Extensions.Configuration;
54

test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using JsonApiDotNetCore.Configuration;
2-
using JsonApiDotNetCoreExampleTests.IntegrationTests;
32
using Microsoft.EntityFrameworkCore;
43
using Microsoft.Extensions.Configuration;
54

test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using JsonApiDotNetCore.Configuration;
2-
using JsonApiDotNetCoreExampleTests.IntegrationTests;
32
using Microsoft.EntityFrameworkCore;
43
using Microsoft.Extensions.Configuration;
54

test/MultiDbContextTests/MultiDbContextTests.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,12 @@
1111

1212
<ItemGroup>
1313
<ProjectReference Include="..\..\src\Examples\MultiDbContextExample\MultiDbContextExample.csproj" />
14+
<ProjectReference Include="..\TestBuildingBlocks\TestBuildingBlocks.csproj" />
1415
</ItemGroup>
1516

1617
<ItemGroup>
17-
<PackageReference Include="FluentAssertions" Version="$(FluentAssertionsVersion)" />
1818
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(AspNetCoreVersion)" />
1919
<PackageReference Include="Moq" Version="$(MoqVersion)" />
20-
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
2120
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
2221
</ItemGroup>
2322
</Project>

test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111

1212
<ItemGroup>
1313
<ProjectReference Include="..\..\src\Examples\NoEntityFrameworkExample\NoEntityFrameworkExample.csproj" />
14+
<ProjectReference Include="..\TestBuildingBlocks\TestBuildingBlocks.csproj" />
1415
</ItemGroup>
1516

1617
<ItemGroup>
1718
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(AspNetCoreVersion)" />
1819
<PackageReference Include="Moq" Version="$(MoqVersion)" />
19-
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
2020
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
2121
</ItemGroup>
2222
</Project>

0 commit comments

Comments
 (0)