Skip to content

Commit 33f5b67

Browse files
authored
Merge pull request #194 from nanotaboada/feature/automapper
feat(service)!: migrate to AutoMapper for Model mapping
2 parents 95b5a8b + ecc10ac commit 33f5b67

File tree

19 files changed

+690
-299
lines changed

19 files changed

+690
-299
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: 157 additions & 108 deletions
Large diffs are not rendered by default.

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

Lines changed: 150 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,32 @@ 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();
29-
30-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
28+
var response = PlayerFakes.CreateResponseModelForOneExistingById(9);
29+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
30+
mapper
31+
.Setup(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<PlayerRequestModel>()))
32+
.Returns(response);
33+
34+
var service = new PlayerService(
35+
repository.Object,
36+
logger.Object,
37+
memoryCache.Object,
38+
mapper.Object
39+
);
3140

3241
// Act
33-
await service.CreateAsync(It.IsAny<Player>());
42+
await service.CreateAsync(It.IsAny<PlayerRequestModel>());
3443

3544
// Assert
3645
repository.Verify(repository => repository.AddAsync(It.IsAny<Player>()), Times.Once);
3746
memoryCache.Verify(cache => cache.Remove(It.IsAny<object>()), Times.Once);
47+
mapper.Verify(
48+
mapper => mapper.Map<PlayerResponseModel>(It.IsAny<PlayerRequestModel>()),
49+
Times.Once
50+
);
3851
}
3952

4053
/* -------------------------------------------------------------------------
@@ -46,12 +59,21 @@ public async Task GivenCreateAsync_WhenRepositoryAddAsync_ThenAddsPlayerToReposi
4659
public async Task GivenRetrieveAsync_WhenRepositoryGetAllAsyncReturnsPlayers_ThenCacheCreateEntryAndResultShouldBeListOfPlayers()
4760
{
4861
// Arrange
49-
var players = PlayerFakes.CreateStarting11();
50-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
62+
var players = PlayerFakes.GetStarting11();
63+
var response = PlayerFakes.CreateStarting11ResponseModels();
64+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
5165
repository.Setup(repository => repository.GetAllAsync()).ReturnsAsync(players);
66+
mapper
67+
.Setup(mapper => mapper.Map<List<PlayerResponseModel>>(It.IsAny<List<Player>>()))
68+
.Returns(response);
5269
var value = It.IsAny<object>();
5370

54-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
71+
var service = new PlayerService(
72+
repository.Object,
73+
logger.Object,
74+
memoryCache.Object,
75+
mapper.Object
76+
);
5577

5678
// Act
5779
var result = await service.RetrieveAsync();
@@ -60,20 +82,33 @@ public async Task GivenRetrieveAsync_WhenRepositoryGetAllAsyncReturnsPlayers_The
6082
repository.Verify(repository => repository.GetAllAsync(), Times.Once);
6183
memoryCache.Verify(cache => cache.TryGetValue(It.IsAny<object>(), out value), Times.Once);
6284
memoryCache.Verify(cache => cache.CreateEntry(It.IsAny<object>()), Times.Once);
63-
result.Should().BeEquivalentTo(players);
85+
mapper.Verify(
86+
mapper => mapper.Map<List<PlayerResponseModel>>(It.IsAny<List<Player>>()),
87+
Times.Once
88+
);
89+
result.Should().BeEquivalentTo(response);
6490
}
6591

6692
[Fact]
6793
[Trait("Category", "Unit")]
6894
public async Task GivenRetrieveAsync_WhenExecutedForTheSecondTime_ThenSecondExecutionTimeShouldBeLessThanFirst()
6995
{
7096
// Arrange
71-
var players = PlayerFakes.CreateStarting11();
72-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks(cacheValue: players);
73-
repository.Setup(repository => repository.GetAllAsync()).ReturnsAsync(players);
97+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
98+
repository
99+
.Setup(repository => repository.GetAllAsync())
100+
.ReturnsAsync(PlayerFakes.GetStarting11());
101+
mapper
102+
.Setup(mapper => mapper.Map<List<PlayerResponseModel>>(It.IsAny<List<Player>>()))
103+
.Returns(PlayerFakes.CreateStarting11ResponseModels());
74104
var value = It.IsAny<object>();
75105

76-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
106+
var service = new PlayerService(
107+
repository.Object,
108+
logger.Object,
109+
memoryCache.Object,
110+
mapper.Object
111+
);
77112

78113
// Act
79114
var first = await ExecutionTimeAsync(() => service.RetrieveAsync());
@@ -84,6 +119,12 @@ public async Task GivenRetrieveAsync_WhenExecutedForTheSecondTime_ThenSecondExec
84119
cache => cache.TryGetValue(It.IsAny<object>(), out value),
85120
Times.Exactly(2) // first + second
86121
);
122+
memoryCache.Verify(cache => cache.CreateEntry(It.IsAny<object>()), Times.Once); // first only
123+
repository.Verify(repository => repository.GetAllAsync(), Times.Once); // first only
124+
mapper.Verify(
125+
mapper => mapper.Map<List<PlayerResponseModel>>(It.IsAny<List<Player>>()),
126+
Times.Once // first only
127+
);
87128
second.Should().BeLessThan(first);
88129
}
89130

@@ -92,17 +133,24 @@ public async Task GivenRetrieveAsync_WhenExecutedForTheSecondTime_ThenSecondExec
92133
public async Task GivenRetrieveByIdAsync_WhenRepositoryFindByIdAsyncReturnsNull_TheResultShouldBeNull()
93134
{
94135
// Arrange
95-
var id = 999;
96-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
97-
repository.Setup(repository => repository.FindByIdAsync(id)).ReturnsAsync((Player?)null);
136+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
137+
repository
138+
.Setup(repository => repository.FindByIdAsync(It.IsAny<long>()))
139+
.ReturnsAsync((Player?)null);
98140

99-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
141+
var service = new PlayerService(
142+
repository.Object,
143+
logger.Object,
144+
memoryCache.Object,
145+
mapper.Object
146+
);
100147

101148
// Act
102-
var result = await service.RetrieveByIdAsync(id);
149+
var result = await service.RetrieveByIdAsync(It.IsAny<long>());
103150

104151
// Assert
105152
repository.Verify(repository => repository.FindByIdAsync(It.IsAny<long>()), Times.Once);
153+
mapper.Verify(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()), Times.Never);
106154
result.Should().BeNull();
107155
}
108156

@@ -111,42 +159,60 @@ public async Task GivenRetrieveByIdAsync_WhenRepositoryFindByIdAsyncReturnsNull_
111159
public async Task GivenRetrieveByIdAsync_WhenRepositoryFindByIdAsyncReturnsPlayer_TheResultShouldBePlayer()
112160
{
113161
// 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);
162+
var id = 9;
163+
var player = PlayerFakes.GetOneExistingById(id);
164+
var response = PlayerFakes.CreateResponseModelForOneExistingById(id);
165+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
166+
repository
167+
.Setup(repository => repository.FindByIdAsync(It.IsAny<long>()))
168+
.ReturnsAsync(player);
169+
mapper
170+
.Setup(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()))
171+
.Returns(response);
172+
173+
var service = new PlayerService(
174+
repository.Object,
175+
logger.Object,
176+
memoryCache.Object,
177+
mapper.Object
178+
);
119179

120180
// Act
121-
var result = await service.RetrieveByIdAsync(player.Id);
181+
var result = await service.RetrieveByIdAsync(It.IsAny<long>());
122182

123183
// Assert
124-
result.Should().BeOfType<Player>();
125-
result.Should().BeEquivalentTo(player);
126184
repository.Verify(repository => repository.FindByIdAsync(It.IsAny<long>()), Times.Once);
185+
mapper.Verify(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()), Times.Once);
186+
result.Should().BeOfType<PlayerResponseModel>();
187+
result.Should().BeEquivalentTo(response);
127188
}
128189

129190
[Fact]
130191
[Trait("Category", "Unit")]
131192
public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumberAsyncReturnsNull_ThenResultShouldBeNull()
132193
{
133194
// Arrange
134-
var squadNumber = 999;
135-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
195+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
136196
repository
137-
.Setup(repository => repository.FindBySquadNumberAsync(squadNumber))
197+
.Setup(repository => repository.FindBySquadNumberAsync(It.IsAny<int>()))
138198
.ReturnsAsync((Player?)null);
139199

140-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
200+
var service = new PlayerService(
201+
repository.Object,
202+
logger.Object,
203+
memoryCache.Object,
204+
mapper.Object
205+
);
141206

142207
// Act
143-
var result = await service.RetrieveBySquadNumberAsync(squadNumber);
208+
var result = await service.RetrieveBySquadNumberAsync(It.IsAny<int>());
144209

145210
// Assert
146211
repository.Verify(
147212
repository => repository.FindBySquadNumberAsync(It.IsAny<int>()),
148213
Times.Once
149214
);
215+
mapper.Verify(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()), Times.Never);
150216
result.Should().BeNull();
151217
}
152218

@@ -155,24 +221,35 @@ public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumbe
155221
public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumberAsyncReturnsPlayer_ThenResultShouldBePlayer()
156222
{
157223
// Arrange
158-
var player = PlayerFakes.CreateOneByIdFromStarting11(9);
159-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
224+
var id = 9;
225+
var player = PlayerFakes.GetOneExistingById(id);
226+
var response = PlayerFakes.CreateResponseModelForOneExistingById(id);
227+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
160228
repository
161-
.Setup(repository => repository.FindBySquadNumberAsync(player.SquadNumber))
229+
.Setup(repository => repository.FindBySquadNumberAsync(It.IsAny<int>()))
162230
.ReturnsAsync(player);
163-
164-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
231+
mapper
232+
.Setup(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()))
233+
.Returns(response);
234+
235+
var service = new PlayerService(
236+
repository.Object,
237+
logger.Object,
238+
memoryCache.Object,
239+
mapper.Object
240+
);
165241

166242
// Act
167-
var result = await service.RetrieveBySquadNumberAsync(player.SquadNumber);
243+
var result = await service.RetrieveBySquadNumberAsync(It.IsAny<int>());
168244

169245
// Assert
170246
repository.Verify(
171247
repository => repository.FindBySquadNumberAsync(It.IsAny<int>()),
172248
Times.Once
173249
);
174-
result.Should().BeOfType<Player>();
175-
result.Should().BeEquivalentTo(player);
250+
mapper.Verify(mapper => mapper.Map<PlayerResponseModel>(It.IsAny<Player>()), Times.Once);
251+
result.Should().BeOfType<PlayerResponseModel>();
252+
result.Should().BeEquivalentTo(response);
176253
}
177254

178255
/* -------------------------------------------------------------------------
@@ -184,19 +261,32 @@ public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumbe
184261
public async Task GivenUpdateAsync_WhenRepositoryFindByIdAsyncReturnsPlayer_ThenRepositoryUpdateAsyncAndCacheRemove()
185262
{
186263
// Arrange
187-
var player = PlayerFakes.CreateOneByIdFromStarting11(9);
188-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
189-
repository.Setup(repository => repository.FindByIdAsync(player.Id)).ReturnsAsync(player);
264+
var id = 9;
265+
var player = PlayerFakes.GetOneExistingById(id);
266+
var request = PlayerFakes.CreateRequestModelForOneExistingById(id);
267+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
268+
repository
269+
.Setup(repository => repository.FindByIdAsync(It.IsAny<long>()))
270+
.ReturnsAsync(player);
190271

191-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
272+
var service = new PlayerService(
273+
repository.Object,
274+
logger.Object,
275+
memoryCache.Object,
276+
mapper.Object
277+
);
192278

193279
// Act
194-
await service.UpdateAsync(player);
280+
await service.UpdateAsync(request);
195281

196282
// Assert
197283
repository.Verify(repository => repository.FindByIdAsync(It.IsAny<long>()), Times.Once);
198-
repository.Verify(repository => repository.UpdateAsync(player), Times.Once);
284+
repository.Verify(repository => repository.UpdateAsync(It.IsAny<Player>()), Times.Once);
199285
memoryCache.Verify(cache => cache.Remove(It.IsAny<object>()), Times.Once);
286+
mapper.Verify(
287+
mapper => mapper.Map(It.IsAny<PlayerRequestModel>(), It.IsAny<Player>()),
288+
Times.Once
289+
);
200290
}
201291

202292
/* -------------------------------------------------------------------------
@@ -208,22 +298,30 @@ public async Task GivenUpdateAsync_WhenRepositoryFindByIdAsyncReturnsPlayer_Then
208298
public async Task GivenDeleteAsync_WhenRepositoryFindByIdAsyncReturnsPlayer_ThenRepositoryDeleteAsyncAndCacheRemove()
209299
{
210300
// Arrange
211-
var player = PlayerFakes.CreateOneNew();
212-
var (repository, logger, memoryCache) = PlayerMocks.SetupServiceMocks();
213-
repository.Setup(repository => repository.FindByIdAsync(player.Id)).ReturnsAsync(player);
301+
var id = 9;
302+
var player = PlayerFakes.GetOneExistingById(id);
303+
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
304+
repository
305+
.Setup(repository => repository.FindByIdAsync(It.IsAny<long>()))
306+
.ReturnsAsync(player);
214307

215-
var service = new PlayerService(repository.Object, logger.Object, memoryCache.Object);
308+
var service = new PlayerService(
309+
repository.Object,
310+
logger.Object,
311+
memoryCache.Object,
312+
mapper.Object
313+
);
216314

217315
// Act
218-
await service.DeleteAsync(player.Id);
316+
await service.DeleteAsync(It.IsAny<long>());
219317

220318
// Assert
221319
repository.Verify(repository => repository.FindByIdAsync(It.IsAny<long>()), Times.Once);
222320
repository.Verify(repository => repository.RemoveAsync(It.IsAny<long>()), Times.Once);
223-
memoryCache.Verify(cache => cache.Remove(It.IsAny<object>()), Times.Exactly(1));
321+
memoryCache.Verify(cache => cache.Remove(It.IsAny<object>()), Times.Once);
224322
}
225323

226-
private async Task<long> ExecutionTimeAsync(Func<Task> awaitable)
324+
private static async Task<long> ExecutionTimeAsync(Func<Task> awaitable)
227325
{
228326
var stopwatch = new Stopwatch();
229327

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)