Skip to content

Commit 53f8c82

Browse files
author
Bart Koelman
committed
Refactored tests for no EF Core
1 parent d9a2ac7 commit 53f8c82

File tree

2 files changed

+52
-79
lines changed

2 files changed

+52
-79
lines changed
Lines changed: 34 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,122 @@
11
using System;
22
using System.Net;
3-
using System.Net.Http;
4-
using System.Net.Http.Headers;
53
using System.Threading.Tasks;
6-
using JsonApiDotNetCore.Middleware;
4+
using FluentAssertions;
75
using JsonApiDotNetCore.Serialization.Objects;
8-
using Microsoft.AspNetCore.Mvc.Testing;
9-
using Microsoft.Extensions.DependencyInjection;
10-
using Newtonsoft.Json;
116
using NoEntityFrameworkExample;
127
using NoEntityFrameworkExample.Data;
138
using NoEntityFrameworkExample.Models;
9+
using TestBuildingBlocks;
1410
using Xunit;
1511

1612
namespace NoEntityFrameworkTests
1713
{
18-
public sealed class WorkItemTests : IClassFixture<WebApplicationFactory<Startup>>
14+
public sealed class WorkItemTests : IClassFixture<RemoteIntegrationTestContext<Startup, AppDbContext>>
1915
{
20-
private readonly WebApplicationFactory<Startup> _factory;
16+
private readonly RemoteIntegrationTestContext<Startup, AppDbContext> _testContext;
2117

22-
public WorkItemTests(WebApplicationFactory<Startup> factory)
18+
public WorkItemTests(RemoteIntegrationTestContext<Startup, AppDbContext> testContext)
2319
{
24-
_factory = factory;
20+
_testContext = testContext;
2521
}
2622

2723
[Fact]
28-
public async Task Can_Get_WorkItems()
24+
public async Task Can_get_WorkItems()
2925
{
3026
// Arrange
31-
await ExecuteOnDbContextAsync(async dbContext =>
27+
await _testContext.RunOnDatabaseAsync(async dbContext =>
3228
{
3329
dbContext.WorkItems.Add(new WorkItem());
3430
await dbContext.SaveChangesAsync();
3531
});
3632

37-
var client = _factory.CreateClient();
38-
39-
var request = new HttpRequestMessage(HttpMethod.Get, "/api/v1/workItems");
33+
var route = "/api/v1/workItems";
4034

4135
// Act
42-
var response = await client.SendAsync(request);
36+
var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync<Document>(route);
4337

4438
// Assert
45-
AssertStatusCode(HttpStatusCode.OK, response);
46-
47-
string responseBody = await response.Content.ReadAsStringAsync();
48-
var document = JsonConvert.DeserializeObject<Document>(responseBody);
39+
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
4940

50-
Assert.NotEmpty(document.ManyData);
41+
responseDocument.ManyData.Should().NotBeEmpty();
5142
}
5243

5344
[Fact]
54-
public async Task Can_Get_WorkItem_By_Id()
45+
public async Task Can_get_WorkItem_by_ID()
5546
{
5647
// Arrange
5748
var workItem = new WorkItem();
5849

59-
await ExecuteOnDbContextAsync(async dbContext =>
50+
await _testContext.RunOnDatabaseAsync(async dbContext =>
6051
{
6152
dbContext.WorkItems.Add(workItem);
6253
await dbContext.SaveChangesAsync();
6354
});
6455

65-
var client = _factory.CreateClient();
66-
67-
var request = new HttpRequestMessage(HttpMethod.Get, "/api/v1/workItems/" + workItem.StringId);
56+
var route = "/api/v1/workItems/" + workItem.StringId;
6857

6958
// Act
70-
var response = await client.SendAsync(request);
59+
var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync<Document>(route);
7160

7261
// Assert
73-
AssertStatusCode(HttpStatusCode.OK, response);
62+
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
7463

75-
string responseBody = await response.Content.ReadAsStringAsync();
76-
var document = JsonConvert.DeserializeObject<Document>(responseBody);
77-
78-
Assert.NotNull(document.SingleData);
79-
Assert.Equal(workItem.StringId, document.SingleData.Id);
64+
responseDocument.SingleData.Should().NotBeNull();
65+
responseDocument.SingleData.Id.Should().Be(workItem.StringId);
8066
}
8167

8268
[Fact]
83-
public async Task Can_Create_WorkItem()
69+
public async Task Can_create_WorkItem()
8470
{
8571
// Arrange
86-
var title = Guid.NewGuid().ToString();
72+
var newTitle = Guid.NewGuid().ToString();
8773

88-
var requestContent = new
74+
var requestBody = new
8975
{
9076
data = new
9177
{
9278
type = "workItems",
9379
attributes = new
9480
{
95-
title,
81+
title = newTitle,
9682
ordinal = 1
9783
}
9884
}
9985
};
10086

101-
var requestBody = JsonConvert.SerializeObject(requestContent);
102-
103-
var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/workItems/")
104-
{
105-
Content = new StringContent(requestBody)
106-
};
107-
request.Content.Headers.ContentType = new MediaTypeHeaderValue(HeaderConstants.MediaType);
108-
109-
var client = _factory.CreateClient();
87+
var route = "/api/v1/workItems/";
11088

11189
// Act
112-
var response = await client.SendAsync(request);
90+
var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync<Document>(route, requestBody);
11391

11492
// Assert
115-
AssertStatusCode(HttpStatusCode.Created, response);
116-
117-
string responseBody = await response.Content.ReadAsStringAsync();
118-
var document = JsonConvert.DeserializeObject<Document>(responseBody);
93+
httpResponse.Should().HaveStatusCode(HttpStatusCode.Created);
11994

120-
Assert.NotNull(document.SingleData);
121-
Assert.Equal(title, document.SingleData.Attributes["title"]);
95+
responseDocument.SingleData.Should().NotBeNull();
96+
responseDocument.SingleData.Attributes["title"].Should().Be(newTitle);
12297
}
12398

12499
[Fact]
125-
public async Task Can_Delete_WorkItem()
100+
public async Task Can_delete_WorkItem()
126101
{
127102
// Arrange
128103
var workItem = new WorkItem();
129104

130-
await ExecuteOnDbContextAsync(async dbContext =>
105+
await _testContext.RunOnDatabaseAsync(async dbContext =>
131106
{
132107
dbContext.WorkItems.Add(workItem);
133108
await dbContext.SaveChangesAsync();
134109
});
135110

136-
var client = _factory.CreateClient();
137-
138-
var request = new HttpRequestMessage(HttpMethod.Delete, "/api/v1/workItems/" + workItem.StringId);
111+
var route = "/api/v1/workItems/" + workItem.StringId;
139112

140113
// Act
141-
var response = await client.SendAsync(request);
114+
var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync<string>(route);
142115

143116
// Assert
144-
AssertStatusCode(HttpStatusCode.NoContent, response);
145-
146-
string responseBody = await response.Content.ReadAsStringAsync();
147-
Assert.Empty(responseBody);
148-
}
149-
150-
private async Task ExecuteOnDbContextAsync(Func<AppDbContext, Task> asyncAction)
151-
{
152-
using IServiceScope scope = _factory.Services.CreateScope();
153-
var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
117+
httpResponse.Should().HaveStatusCode(HttpStatusCode.NoContent);
154118

155-
await asyncAction(dbContext);
156-
}
157-
158-
private static void AssertStatusCode(HttpStatusCode expected, HttpResponseMessage response)
159-
{
160-
if (expected != response.StatusCode)
161-
{
162-
var responseBody = response.Content.ReadAsStringAsync().Result;
163-
Assert.True(expected == response.StatusCode, $"Got {response.StatusCode} status code instead of {expected}. Response body: {responseBody}");
164-
}
119+
responseDocument.Should().BeEmpty();
165120
}
166121
}
167122
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace TestBuildingBlocks
4+
{
5+
/// <summary>
6+
/// A test context that creates a new database and server instance before running tests and cleans up afterwards.
7+
/// You can either use this as a fixture on your tests class (init/cleanup runs once before/after all tests) or
8+
/// have your tests class inherit from it (init/cleanup runs once before/after each test). See
9+
/// <see href="https://xunit.net/docs/shared-context"/> for details on shared context usage.
10+
/// </summary>
11+
/// <typeparam name="TStartup">The server Startup class, which MUST be defined in the API project.</typeparam>
12+
/// <typeparam name="TDbContext">The EF Core database context, which MUST be defined in the API project.</typeparam>
13+
public class RemoteIntegrationTestContext<TStartup, TDbContext> : BaseIntegrationTestContext<TStartup, TStartup, TDbContext>
14+
where TStartup : class
15+
where TDbContext : DbContext
16+
{
17+
}
18+
}

0 commit comments

Comments
 (0)