Skip to content

Commit 6a6d5a6

Browse files
committed
feat(service)!: migrate to AutoMapper for model mapping
1 parent 95b5a8b commit 6a6d5a6

File tree

19 files changed

+610
-271
lines changed

19 files changed

+610
-271
lines changed

.codacy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ exclude_paths:
1313
- "**/*Program.cs"
1414
- "**/Data/**"
1515
- "**/Enums/**"
16+
- "**/Mappings/**"
1617
- "**/Migrations/**"
1718
- "**/Models/**"
1819
- "**/Properties/**"

Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs

Lines changed: 103 additions & 89 deletions
Large diffs are not rendered by default.

Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerServiceTests.cs

Lines changed: 136 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@ public PlayerServiceTests()
2222

2323
[Fact]
2424
[Trait("Category", "Unit")]
25-
public async Task GivenCreateAsync_WhenRepositoryAddAsync_ThenAddsPlayerToRepositoryAndRemovesMemoryCache()
25+
public async Task GivenCreateAsync_WhenRepositoryAddAsync_ThenAddsPlayerToRepositoryAndRemovesCache()
2626
{
2727
// Arrange
28-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
28+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
2929

30-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
30+
var service = new PlayerService(
31+
repository.Object,
32+
logger.Object,
33+
memoryCache.Object,
34+
mapper.Object
35+
);
3136

3237
// Act
33-
await service.CreateAsync(It.IsAny<Player>());
38+
await service.CreateAsync(It.IsAny<PlayerRequestModel>());
3439

3540
// Assert
3641
repository.Verify(repository => repository.AddAsync(It.IsAny<Player>()), Times.Once);
@@ -46,12 +51,21 @@ public async Task GivenCreateAsync_WhenRepositoryAddAsync_ThenAddsPlayerToReposi
4651
public async Task GivenRetrieveAsync_WhenRepositoryGetAllAsyncReturnsPlayers_ThenCacheCreateEntryAndResultShouldBeListOfPlayers()
4752
{
4853
// Arrange
49-
var players = PlayerFakes.CreateStarting11();
50-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
54+
var players = PlayerFakes.GetStarting11();
55+
var response = PlayerFakes.CreateStarting11ResponseModels();
56+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
5157
repository.Setup(repository => repository.GetAllAsync()).ReturnsAsync(players);
58+
mapper
59+
.Setup(mapper => mapper.Map<List<PlayerResponseModel>>(It.IsAny<List<Player>>()))
60+
.Returns(response);
5261
var value = It.IsAny<object>();
5362

54-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
63+
var service = new PlayerService(
64+
repository.Object,
65+
logger.Object,
66+
memoryCache.Object,
67+
mapper.Object
68+
);
5569

5670
// Act
5771
var result = await service.RetrieveAsync();
@@ -60,20 +74,33 @@ public async Task GivenRetrieveAsync_WhenRepositoryGetAllAsyncReturnsPlayers_The
6074
repository.Verify(repository => repository.GetAllAsync(), Times.Once);
6175
memoryCache.Verify(cache => cache.TryGetValue(It.IsAny<object>(), out value), Times.Once);
6276
memoryCache.Verify(cache => cache.CreateEntry(It.IsAny<object>()), Times.Once);
63-
result.Should().BeEquivalentTo(players);
77+
mapper.Verify(
78+
mapper => mapper.Map<List<PlayerResponseModel>>(It.IsAny<List<Player>>()),
79+
Times.Once
80+
);
81+
result.Should().BeEquivalentTo(response);
6482
}
6583

6684
[Fact]
6785
[Trait("Category", "Unit")]
6886
public async Task GivenRetrieveAsync_WhenExecutedForTheSecondTime_ThenSecondExecutionTimeShouldBeLessThanFirst()
6987
{
7088
// Arrange
71-
var players = PlayerFakes.CreateStarting11();
72-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks(cacheValue: players);
73-
repository.Setup(repository => repository.GetAllAsync()).ReturnsAsync(players);
89+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
90+
repository
91+
.Setup(repository => repository.GetAllAsync())
92+
.ReturnsAsync(PlayerFakes.GetStarting11());
93+
mapper
94+
.Setup(mapper => mapper.Map<List<PlayerResponseModel>>(It.IsAny<List<Player>>()))
95+
.Returns(PlayerFakes.CreateStarting11ResponseModels());
7496
var value = It.IsAny<object>();
7597

76-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
98+
var service = new PlayerService(
99+
repository.Object,
100+
logger.Object,
101+
memoryCache.Object,
102+
mapper.Object
103+
);
77104

78105
// Act
79106
var first = await ExecutionTimeAsync(() => service.RetrieveAsync());
@@ -84,6 +111,10 @@ public async Task GivenRetrieveAsync_WhenExecutedForTheSecondTime_ThenSecondExec
84111
cache => cache.TryGetValue(It.IsAny<object>(), out value),
85112
Times.Exactly(2) // first + second
86113
);
114+
mapper.Verify(
115+
mapper => mapper.Map<List<PlayerResponseModel>>(It.IsAny<List<Player>>()),
116+
Times.Once // first only
117+
);
87118
second.Should().BeLessThan(first);
88119
}
89120

@@ -92,14 +123,20 @@ public async Task GivenRetrieveAsync_WhenExecutedForTheSecondTime_ThenSecondExec
92123
public async Task GivenRetrieveByIdAsync_WhenRepositoryFindByIdAsyncReturnsNull_TheResultShouldBeNull()
93124
{
94125
// Arrange
95-
var id = 999;
96-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
97-
repository.Setup(repository => repository.FindByIdAsync(id)).ReturnsAsync((Player?)null);
126+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
127+
repository
128+
.Setup(repository => repository.FindByIdAsync(It.IsAny<long>()))
129+
.ReturnsAsync((Player?)null);
98130

99-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
131+
var service = new PlayerService(
132+
repository.Object,
133+
logger.Object,
134+
memoryCache.Object,
135+
mapper.Object
136+
);
100137

101138
// Act
102-
var result = await service.RetrieveByIdAsync(id);
139+
var result = await service.RetrieveByIdAsync(It.IsAny<long>());
103140

104141
// Assert
105142
repository.Verify(repository => repository.FindByIdAsync(It.IsAny<long>()), Times.Once);
@@ -111,36 +148,53 @@ public async Task GivenRetrieveByIdAsync_WhenRepositoryFindByIdAsyncReturnsNull_
111148
public async Task GivenRetrieveByIdAsync_WhenRepositoryFindByIdAsyncReturnsPlayer_TheResultShouldBePlayer()
112149
{
113150
// Arrange
114-
var player = PlayerFakes.CreateOneByIdFromStarting11(9);
115-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
116-
repository.Setup(repository => repository.FindByIdAsync(player.Id)).ReturnsAsync(player);
117-
118-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
151+
var id = 9;
152+
var player = PlayerFakes.GetOneExistingById(id);
153+
var response = PlayerFakes.CreateResponseModelForOneExistingById(id);
154+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
155+
repository
156+
.Setup(repository => repository.FindByIdAsync(It.IsAny<long>()))
157+
.ReturnsAsync(player);
158+
mapper
159+
.Setup(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()))
160+
.Returns(response);
161+
162+
var service = new PlayerService(
163+
repository.Object,
164+
logger.Object,
165+
memoryCache.Object,
166+
mapper.Object
167+
);
119168

120169
// Act
121-
var result = await service.RetrieveByIdAsync(player.Id);
170+
var result = await service.RetrieveByIdAsync(It.IsAny<long>());
122171

123172
// Assert
124-
result.Should().BeOfType<Player>();
125-
result.Should().BeEquivalentTo(player);
126173
repository.Verify(repository => repository.FindByIdAsync(It.IsAny<long>()), Times.Once);
174+
mapper.Verify(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()), Times.Once);
175+
result.Should().BeOfType<PlayerResponseModel>();
176+
result.Should().BeEquivalentTo(response);
127177
}
128178

129179
[Fact]
130180
[Trait("Category", "Unit")]
131181
public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumberAsyncReturnsNull_ThenResultShouldBeNull()
132182
{
133183
// Arrange
134-
var squadNumber = 999;
135-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
184+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
136185
repository
137-
.Setup(repository => repository.FindBySquadNumberAsync(squadNumber))
186+
.Setup(repository => repository.FindBySquadNumberAsync(It.IsAny<int>()))
138187
.ReturnsAsync((Player?)null);
139188

140-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
189+
var service = new PlayerService(
190+
repository.Object,
191+
logger.Object,
192+
memoryCache.Object,
193+
mapper.Object
194+
);
141195

142196
// Act
143-
var result = await service.RetrieveBySquadNumberAsync(squadNumber);
197+
var result = await service.RetrieveBySquadNumberAsync(It.IsAny<int>());
144198

145199
// Assert
146200
repository.Verify(
@@ -155,24 +209,35 @@ public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumbe
155209
public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumberAsyncReturnsPlayer_ThenResultShouldBePlayer()
156210
{
157211
// Arrange
158-
var player = PlayerFakes.CreateOneByIdFromStarting11(9);
159-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
212+
var id = 9;
213+
var player = PlayerFakes.GetOneExistingById(id);
214+
var response = PlayerFakes.CreateResponseModelForOneExistingById(id);
215+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
160216
repository
161-
.Setup(repository => repository.FindBySquadNumberAsync(player.SquadNumber))
217+
.Setup(repository => repository.FindBySquadNumberAsync(It.IsAny<int>()))
162218
.ReturnsAsync(player);
163-
164-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
219+
mapper
220+
.Setup(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()))
221+
.Returns(response);
222+
223+
var service = new PlayerService(
224+
repository.Object,
225+
logger.Object,
226+
memoryCache.Object,
227+
mapper.Object
228+
);
165229

166230
// Act
167-
var result = await service.RetrieveBySquadNumberAsync(player.SquadNumber);
231+
var result = await service.RetrieveBySquadNumberAsync(It.IsAny<int>());
168232

169233
// Assert
170234
repository.Verify(
171235
repository => repository.FindBySquadNumberAsync(It.IsAny<int>()),
172236
Times.Once
173237
);
174-
result.Should().BeOfType<Player>();
175-
result.Should().BeEquivalentTo(player);
238+
mapper.Verify(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()), Times.Once);
239+
result.Should().BeOfType<PlayerResponseModel>();
240+
result.Should().BeEquivalentTo(response);
176241
}
177242

178243
/* -------------------------------------------------------------------------
@@ -184,19 +249,32 @@ public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumbe
184249
public async Task GivenUpdateAsync_WhenRepositoryFindByIdAsyncReturnsPlayer_ThenRepositoryUpdateAsyncAndCacheRemove()
185250
{
186251
// Arrange
187-
var player = PlayerFakes.CreateOneByIdFromStarting11(9);
188-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
189-
repository.Setup(repository => repository.FindByIdAsync(player.Id)).ReturnsAsync(player);
252+
var id = 9;
253+
var player = PlayerFakes.GetOneExistingById(id);
254+
var request = PlayerFakes.CreateRequestModelForOneExistingById(id);
255+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
256+
repository
257+
.Setup(repository => repository.FindByIdAsync(It.IsAny<long>()))
258+
.ReturnsAsync(player);
190259

191-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
260+
var service = new PlayerService(
261+
repository.Object,
262+
logger.Object,
263+
memoryCache.Object,
264+
mapper.Object
265+
);
192266

193267
// Act
194-
await service.UpdateAsync(player);
268+
await service.UpdateAsync(request);
195269

196270
// Assert
197271
repository.Verify(repository => repository.FindByIdAsync(It.IsAny<long>()), Times.Once);
198-
repository.Verify(repository => repository.UpdateAsync(player), Times.Once);
272+
repository.Verify(repository => repository.UpdateAsync(It.IsAny<Player>()), Times.Once);
199273
memoryCache.Verify(cache => cache.Remove(It.IsAny<object>()), Times.Once);
274+
mapper.Verify(
275+
mapper => mapper.Map(It.IsAny<PlayerRequestModel>(), It.IsAny<Player>()),
276+
Times.Once
277+
);
200278
}
201279

202280
/* -------------------------------------------------------------------------
@@ -208,22 +286,30 @@ public async Task GivenUpdateAsync_WhenRepositoryFindByIdAsyncReturnsPlayer_Then
208286
public async Task GivenDeleteAsync_WhenRepositoryFindByIdAsyncReturnsPlayer_ThenRepositoryDeleteAsyncAndCacheRemove()
209287
{
210288
// Arrange
211-
var player = PlayerFakes.CreateOneNew();
212-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
213-
repository.Setup(repository => repository.FindByIdAsync(player.Id)).ReturnsAsync(player);
289+
var id = 9;
290+
var player = PlayerFakes.GetOneExistingById(id);
291+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
292+
repository
293+
.Setup(repository => repository.FindByIdAsync(It.IsAny<long>()))
294+
.ReturnsAsync(player);
214295

215-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
296+
var service = new PlayerService(
297+
repository.Object,
298+
logger.Object,
299+
memoryCache.Object,
300+
mapper.Object
301+
);
216302

217303
// Act
218-
await service.DeleteAsync(player.Id);
304+
await service.DeleteAsync(It.IsAny<long>());
219305

220306
// Assert
221307
repository.Verify(repository => repository.FindByIdAsync(It.IsAny<long>()), Times.Once);
222308
repository.Verify(repository => repository.RemoveAsync(It.IsAny<long>()), Times.Once);
223309
memoryCache.Verify(cache => cache.Remove(It.IsAny<object>()), Times.Exactly(1));
224310
}
225311

226-
private async Task<long> ExecutionTimeAsync(Func<Task> awaitable)
312+
private static async Task<long> ExecutionTimeAsync(Func<Task> awaitable)
227313
{
228314
var stopwatch = new Stopwatch();
229315

Dotnet.Samples.AspNetCore.WebApi.Tests/Utilities/DatabaseFakes.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ CREATE TABLE players (
4848

4949
public static void Seed(this PlayerDbContext context)
5050
{
51-
context.Players.AddRange(PlayerFakes.CreateStarting11());
51+
context.Players.AddRange(PlayerFakes.GetStarting11());
5252
context.SaveChanges();
5353
}
5454
}

0 commit comments

Comments
 (0)