-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(unittests): added all the remaining tests for Expenses and pendi…
…ng GetAllCategoriesQuery tests; used MockQueryable.Moq library to handle IAsyncQueriableProvider implementation
- Loading branch information
Showing
11 changed files
with
368 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
tests/UnitTests/Features/Commands/DeleteExpenseCommandHandlerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
namespace Application.UnitTests.Expenses.PostAsync; | ||
|
||
public sealed class DeleteExpenseCommandHandlerTests | ||
{ | ||
private readonly CancellationToken _cancellationToken; | ||
private readonly Mock<IExpensesRepository> _repository; | ||
private readonly Mock<IUnitOfWork> _uow; | ||
private readonly DeleteExpenseCommandHandler _handler; | ||
|
||
public DeleteExpenseCommandHandlerTests() | ||
{ | ||
_cancellationToken = new(); | ||
_repository = new(); | ||
_uow = new(); | ||
|
||
_handler = new DeleteExpenseCommandHandler(_repository.Object, _uow.Object); | ||
} | ||
|
||
[Fact] | ||
public async Task DeleteExpenseCommandHandler_ShouldDeleteExpense() | ||
{ | ||
// Arrange | ||
var deleteExpenseCommand = new DeleteExpenseCommand(Guid.NewGuid()); | ||
_repository | ||
.Setup(mock => mock.DeleteAsync(It.IsAny<Guid>(), _cancellationToken)) | ||
.Verifiable(); | ||
_uow.Setup(mock => mock.SaveChangesAsync(_cancellationToken)).Verifiable(); | ||
|
||
// Act | ||
await _handler.Handle(deleteExpenseCommand, _cancellationToken); | ||
|
||
// Assert | ||
_repository.Verify( | ||
mock => mock.DeleteAsync(It.IsAny<Guid>(), _cancellationToken), | ||
Times.Once | ||
); | ||
_uow.Verify(mock => mock.SaveChangesAsync(_cancellationToken), Times.Once); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
tests/UnitTests/Features/Commands/PatchExpenseCommandHandlerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
namespace Application.UnitTests.Expenses.PostAsync; | ||
|
||
public sealed class PatchExpenseCommandHandlerTests | ||
{ | ||
private readonly CancellationToken _cancellationToken; | ||
private readonly Mock<IValidator<PatchExpenseCommand>> _validator; | ||
private readonly Mock<IExpensesRepository> _repository; | ||
private readonly Mock<IUnitOfWork> _uow; | ||
private readonly Mock<IEventBus> _eventBus; | ||
private readonly PatchExpenseCommandHandler _handler; | ||
|
||
public PatchExpenseCommandHandlerTests() | ||
{ | ||
_cancellationToken = new(); | ||
_validator = new(); | ||
_repository = new(); | ||
_uow = new(); | ||
_eventBus = new(); | ||
|
||
_handler = new PatchExpenseCommandHandler( | ||
_validator.Object, | ||
_repository.Object, | ||
_uow.Object, | ||
_eventBus.Object | ||
); | ||
} | ||
|
||
[Fact] | ||
public async Task PatchExpenseCommandHandler_ShouldPatchExpenseAndPublishEventAsync() | ||
{ | ||
// Arrange | ||
var patchExpenseCommand = new PatchExpenseCommand( | ||
Guid.NewGuid(), | ||
"Expense 1 name", | ||
"Expense 1 description", | ||
1, | ||
new Guid() | ||
); | ||
_validator | ||
.Setup(mock => mock.ValidateAsync(It.IsAny<PatchExpenseCommand>(), _cancellationToken)) | ||
.ReturnsAsync(new ValidationResult()) | ||
.Verifiable(); | ||
_repository | ||
.Setup(mock => mock.PatchAsync(It.IsAny<Expense>(), _cancellationToken)) | ||
.Verifiable(); | ||
_uow.Setup(mock => mock.SaveChangesAsync(_cancellationToken)).Verifiable(); | ||
_eventBus | ||
.Setup(mock => mock.PublishAsync(It.IsAny<PatchedExpenseEvent>(), _cancellationToken)) | ||
.Verifiable(); | ||
|
||
// Act | ||
await _handler.Handle(patchExpenseCommand, _cancellationToken); | ||
|
||
// Assert | ||
_validator.Verify( | ||
mock => mock.ValidateAsync(It.IsAny<PatchExpenseCommand>(), _cancellationToken), | ||
Times.Once | ||
); | ||
_repository.Verify( | ||
mock => mock.PatchAsync(It.IsAny<Expense>(), _cancellationToken), | ||
Times.Once | ||
); | ||
_uow.Verify(mock => mock.SaveChangesAsync(_cancellationToken), Times.Once); | ||
_eventBus.Verify( | ||
mock => mock.PublishAsync(It.IsAny<PatchedExpenseEvent>(), _cancellationToken), | ||
Times.Once | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
tests/UnitTests/Features/Commands/PostExpenseCommandHandlerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
namespace Application.UnitTests.Expenses.PostAsync; | ||
|
||
public sealed class PostExpenseCommandHandlerTests | ||
{ | ||
private readonly CancellationToken _cancellationToken; | ||
private readonly Mock<IValidator<PostExpenseCommand>> _validator; | ||
private readonly Mock<IExpensesRepository> _repository; | ||
private readonly Mock<IUnitOfWork> _uow; | ||
private readonly Mock<IEventBus> _eventBus; | ||
private readonly PostExpenseCommandHandler _handler; | ||
|
||
public PostExpenseCommandHandlerTests() | ||
{ | ||
_cancellationToken = new(); | ||
_validator = new(); | ||
_repository = new(); | ||
_uow = new(); | ||
_eventBus = new(); | ||
|
||
_handler = new PostExpenseCommandHandler( | ||
_validator.Object, | ||
_repository.Object, | ||
_uow.Object, | ||
_eventBus.Object | ||
); | ||
} | ||
|
||
[Fact] | ||
public async Task PostExpenseCommandHandler_ShouldPostExpenseAndPublishEventAsync() | ||
{ | ||
// Arrange | ||
var postExpenseCommand = new PostExpenseCommand( | ||
"Expense 1 name", | ||
"Expense 1 description", | ||
1, | ||
new Guid() | ||
); | ||
_validator | ||
.Setup(mock => mock.ValidateAsync(postExpenseCommand, _cancellationToken)) | ||
.ReturnsAsync(new ValidationResult()) | ||
.Verifiable(); | ||
_repository | ||
.Setup(mock => mock.PostAsync(It.IsAny<Expense>(), _cancellationToken)) | ||
.Verifiable(); | ||
_uow.Setup(mock => mock.SaveChangesAsync(_cancellationToken)).Verifiable(); | ||
_eventBus | ||
.Setup(mock => mock.PublishAsync(It.IsAny<PostedExpenseEvent>(), _cancellationToken)) | ||
.Verifiable(); | ||
|
||
// Act | ||
await _handler.Handle(postExpenseCommand, _cancellationToken); | ||
|
||
// Assert | ||
_validator.Verify( | ||
mock => mock.ValidateAsync(It.IsAny<PostExpenseCommand>(), _cancellationToken), | ||
Times.Once | ||
); | ||
_repository.Verify( | ||
mock => mock.PostAsync(It.IsAny<Expense>(), _cancellationToken), | ||
Times.Once | ||
); | ||
_uow.Verify(mock => mock.SaveChangesAsync(_cancellationToken), Times.Once); | ||
_eventBus.Verify( | ||
mock => mock.PublishAsync(It.IsAny<PostedExpenseEvent>(), _cancellationToken), | ||
Times.Once | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
tests/UnitTests/Features/Queries/GetAllExpensesQueryHandlerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
namespace UnitTests.Features.Queries; | ||
|
||
public sealed class GetAllExpensesQueryHandlerTests | ||
{ | ||
private readonly CancellationToken _cancellationToken; | ||
private readonly Mock<IExpensesRepository> _repository; | ||
private readonly Mock<IRedisCache> _redisCache; | ||
private readonly GetAllExpensesQueryHandler _handler; | ||
|
||
public GetAllExpensesQueryHandlerTests() | ||
{ | ||
_cancellationToken = new(); | ||
_repository = new(); | ||
_redisCache = new(); | ||
|
||
_handler = new GetAllExpensesQueryHandler(_repository.Object, _redisCache.Object); | ||
} | ||
|
||
[Fact] | ||
public async Task GetAllExpensesQueryHandler_ShouldReturnPagedListOfRequestedExpensesAsListOfExpenseDTOAndMetadata() | ||
{ | ||
// Arrange | ||
var containedWord = "am"; | ||
var page = 1; | ||
var pageSize = 2; | ||
var getAllExpensesQuery = new GetAllExpensesQuery | ||
{ | ||
Page = page, | ||
PageSize = pageSize, | ||
ContainedWord = containedWord, | ||
}; | ||
var redisKey = $"{nameof(GetAllExpensesQuery)}#{page}#{pageSize}"; | ||
var expenses = new List<Expense> | ||
{ | ||
new() | ||
{ | ||
Id = Guid.NewGuid(), | ||
Name = "Name 1", | ||
Description = "Description 1", | ||
Value = 1, | ||
}, | ||
new() | ||
{ | ||
Id = Guid.NewGuid(), | ||
Name = "Name 2", | ||
Description = "Description 2", | ||
Value = 2, | ||
}, | ||
}; | ||
_repository | ||
.Setup(mock => mock.ApplySpecification(It.IsAny<ExpensesSpecification>())) | ||
.Returns(expenses.BuildMock()) | ||
.Verifiable(); | ||
_redisCache | ||
.Setup(mock => mock.GetCachedData<PagedList<ExpenseDTO>>(redisKey)) | ||
.ReturnsAsync((PagedList<ExpenseDTO>)null!); | ||
_redisCache | ||
.Setup(mock => | ||
mock.SetCachedData( | ||
redisKey, | ||
It.IsAny<PagedList<ExpenseDTO>>(), | ||
It.IsAny<DateTimeOffset>() | ||
) | ||
) | ||
.Returns(Task.CompletedTask) | ||
.Verifiable(); | ||
|
||
// Act | ||
var result = await _handler.Handle(getAllExpensesQuery, _cancellationToken); | ||
|
||
// Assert | ||
result.Items[0].Id.Should().Be(expenses[0].Id); | ||
result.Items[0].Name.Should().Be(expenses[0].Name); | ||
result.Items[0].Description.Should().Be(expenses[0].Description); | ||
result.Items[0].Value.Should().Be(expenses[0].Value); | ||
result.Items[1].Id.Should().Be(expenses[1].Id); | ||
result.Items[1].Name.Should().Be(expenses[1].Name); | ||
result.Items[1].Value.Should().Be(expenses[1].Value); | ||
result.TotalCount.Should().Be(expenses.Count); | ||
result.Page.Should().Be(page); | ||
result.PageSize.Should().Be(pageSize); | ||
result.HasPreviousPage.Should().Be(false); | ||
result.HasNextPage.Should().Be(false); | ||
_repository.Verify( | ||
mock => mock.ApplySpecification(It.IsAny<ExpensesSpecification>()), | ||
Times.Once | ||
); | ||
_redisCache.Verify(mock => mock.GetCachedData<PagedList<ExpenseDTO>>(redisKey), Times.Once); | ||
_redisCache.Verify( | ||
mock => | ||
mock.SetCachedData( | ||
redisKey, | ||
It.IsAny<PagedList<ExpenseDTO>>(), | ||
It.IsAny<DateTimeOffset>() | ||
), | ||
Times.Once | ||
); | ||
} | ||
} |
Oops, something went wrong.