From ab908f26cef0ef75da8c24fd4a1283bb44cfc41e Mon Sep 17 00:00:00 2001 From: babisque Date: Mon, 27 May 2024 21:36:59 -0300 Subject: [PATCH 1/2] Tests are added --- Catalog/Catalog.API/Program.cs | 2 - Catalog/Catalog.Test/Catalog.Test.csproj | 35 +++ Catalog/Catalog.Test/GlobalUsings.cs | 1 + .../Catalog.Test/ProductControllerTests.cs | 207 ++++++++++++++++++ Catalog/Catalog.Test/UnitTest1.cs | 9 + Catalog/Catalog.sln | 6 + 6 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 Catalog/Catalog.Test/Catalog.Test.csproj create mode 100644 Catalog/Catalog.Test/GlobalUsings.cs create mode 100644 Catalog/Catalog.Test/ProductControllerTests.cs create mode 100644 Catalog/Catalog.Test/UnitTest1.cs diff --git a/Catalog/Catalog.API/Program.cs b/Catalog/Catalog.API/Program.cs index 4d0fdf3..a43dfb9 100644 --- a/Catalog/Catalog.API/Program.cs +++ b/Catalog/Catalog.API/Program.cs @@ -8,8 +8,6 @@ var builder = WebApplication.CreateBuilder(args); -/*builder.Services.AddAutoMapper(typeof());*/ - var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); diff --git a/Catalog/Catalog.Test/Catalog.Test.csproj b/Catalog/Catalog.Test/Catalog.Test.csproj new file mode 100644 index 0000000..b58e52e --- /dev/null +++ b/Catalog/Catalog.Test/Catalog.Test.csproj @@ -0,0 +1,35 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + diff --git a/Catalog/Catalog.Test/GlobalUsings.cs b/Catalog/Catalog.Test/GlobalUsings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/Catalog/Catalog.Test/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/Catalog/Catalog.Test/ProductControllerTests.cs b/Catalog/Catalog.Test/ProductControllerTests.cs new file mode 100644 index 0000000..5777130 --- /dev/null +++ b/Catalog/Catalog.Test/ProductControllerTests.cs @@ -0,0 +1,207 @@ +using Catalog.API.Controllers; +using Catalog.Core.DTO; +using Catalog.Core.Entities; +using Catalog.Core.Repositories; +using FluentValidation; +using FluentValidation.Results; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Moq; + +namespace Catalog.Test; + +public class ProductControllerTests +{ + private readonly Mock _productRepositoryMock; + private readonly Mock> _loggerMock; + private readonly Mock> _validatorMock; + private readonly ProductController _controller; + + public ProductControllerTests() + { + _productRepositoryMock = new Mock(); + _loggerMock = new Mock>(); + _validatorMock = new Mock>(); + _controller = new ProductController(_productRepositoryMock.Object, _loggerMock.Object, _validatorMock.Object); + } + + [Fact] + public async Task Post_ValidProduct_ReturnsCreatedResult() + { + // Arrange + var productDtoRequest = new ProductDtoRequest + { + Name = "Test Product", + Description = "Test Description", + Price = 100, + Category = "Test Category", + Stock = 10, + Image = null + }; + + var product = new Product + { + Id = 1, + Name = productDtoRequest.Name, + Description = productDtoRequest.Description, + Price = productDtoRequest.Price, + Category = productDtoRequest.Category, + Stock = productDtoRequest.Stock + }; + + _validatorMock.Setup(v => v.ValidateAsync(It.IsAny(), default)) + .ReturnsAsync(new ValidationResult()); + + _productRepositoryMock.Setup(repo => repo.CreateAsync(It.IsAny())) + .Returns(Task.CompletedTask); + + // Act + var result = await _controller.Post(productDtoRequest); + + // Assert + var createdResult = Assert.IsType(result.Result); + var returnValue = Assert.IsType(createdResult.Value); + Assert.Equal(product.Name, returnValue.Name); + _productRepositoryMock.Verify(repo => repo.CreateAsync(It.IsAny()), Times.Once); + } + + [Fact] + public async Task Post_InvalidProduct_ReturnsBadRequest() + { + // Arrange + var productDtoRequest = new ProductDtoRequest + { + Name = "Test Product", + Description = "Test Description", + Price = 100, + Category = "Test Category", + Stock = 10, + Image = null + }; + + var validationFailures = new List + { + new ValidationFailure("Name", "Name is required") + }; + + _validatorMock.Setup(v => v.ValidateAsync(It.IsAny(), default)) + .ReturnsAsync(new ValidationResult(validationFailures)); + + // Act + var result = await _controller.Post(productDtoRequest); + + // Assert + var badRequestResult = Assert.IsType(result.Result); + var problemDetails = Assert.IsType(badRequestResult.Value); + Assert.Contains("Name", problemDetails.Errors); + } + + [Fact] + public async Task Get_ReturnsOkWithProducts() + { + // Arrange + var products = new List + { + new Product { Id = 1, Name = "Product 1" }, + new Product { Id = 2, Name = "Product 2" } + }; + + _productRepositoryMock.Setup(repo => repo.GetAllAsync()) + .ReturnsAsync(products); + + // Act + var result = await _controller.Get(); + + // Assert + var okResult = Assert.IsType(result); + var returnValue = Assert.IsType>(okResult.Value); + Assert.Equal(2, returnValue.Count); + } + + [Fact] + public async Task GetProduct_ExistingId_ReturnsOk() + { + // Arrange + var product = new Product { Id = 1, Name = "Product 1" }; + + _productRepositoryMock.Setup(repo => repo.GetByIdAsync(1)) + .ReturnsAsync(product); + + // Act + var result = await _controller.GetProduct(1); + + // Assert + var okResult = Assert.IsType(result.Result); + var returnValue = Assert.IsType(okResult.Value); + Assert.Equal(product.Name, returnValue.Name); + } + + [Fact] + public async Task GetProduct_NonExistingId_ReturnsNotFound() + { + // Arrange + _productRepositoryMock.Setup(repo => repo.GetByIdAsync(1)) + .ReturnsAsync((Product)null); + + // Act + var result = await _controller.GetProduct(1); + + // Assert + Assert.IsType(result.Result); + } + + [Fact] + public async Task Put_ValidUpdate_ReturnsOk() + { + // Arrange + var product = new Product { Id = 1, Name = "Product 1", Price = 100 }; + var updateDto = new ProductDtoUpdate { Name = "Updated Product", Price = 150 }; + + _productRepositoryMock.Setup(repo => repo.GetByIdAsync(1)) + .ReturnsAsync(product); + + _productRepositoryMock.Setup(repo => repo.UpdateAsync(It.IsAny())) + .Returns(Task.CompletedTask); + + // Act + var result = await _controller.Put(1, updateDto); + + // Assert + Assert.IsType(result); + _productRepositoryMock.Verify(repo => repo.UpdateAsync(It.IsAny()), Times.Once); + } + + [Fact] + public async Task Delete_ExistingId_ReturnsOk() + { + // Arrange + var product = new Product { Id = 1, Name = "Product 1" }; + + _productRepositoryMock.Setup(repo => repo.GetByIdAsync(1)) + .ReturnsAsync(product); + + _productRepositoryMock.Setup(repo => repo.RemoveAsync(1)) + .Returns(Task.CompletedTask); + + // Act + var result = await _controller.Delete(1); + + // Assert + Assert.IsType(result); + _productRepositoryMock.Verify(repo => repo.RemoveAsync(1), Times.Once); + } + + [Fact] + public async Task Delete_NonExistingId_ReturnsNotFound() + { + // Arrange + _productRepositoryMock.Setup(repo => repo.GetByIdAsync(1)) + .ReturnsAsync((Product)null); + + // Act + var result = await _controller.Delete(1); + + // Assert + Assert.IsType(result); + } +} \ No newline at end of file diff --git a/Catalog/Catalog.Test/UnitTest1.cs b/Catalog/Catalog.Test/UnitTest1.cs new file mode 100644 index 0000000..899d4b3 --- /dev/null +++ b/Catalog/Catalog.Test/UnitTest1.cs @@ -0,0 +1,9 @@ +namespace Catalog.Test; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + } +} \ No newline at end of file diff --git a/Catalog/Catalog.sln b/Catalog/Catalog.sln index 8acef2c..c678647 100644 --- a/Catalog/Catalog.sln +++ b/Catalog/Catalog.sln @@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Catalog.Infrastructure", "C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Catalog.Core", "Catalog.Core\Catalog.Core.csproj", "{8BB165BC-4495-4D19-848B-E4171E76E12E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Catalog.Test", "Catalog.Test\Catalog.Test.csproj", "{433F961A-EFEA-4E51-ABD5-26B03E226775}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -24,5 +26,9 @@ Global {8BB165BC-4495-4D19-848B-E4171E76E12E}.Debug|Any CPU.Build.0 = Debug|Any CPU {8BB165BC-4495-4D19-848B-E4171E76E12E}.Release|Any CPU.ActiveCfg = Release|Any CPU {8BB165BC-4495-4D19-848B-E4171E76E12E}.Release|Any CPU.Build.0 = Release|Any CPU + {433F961A-EFEA-4E51-ABD5-26B03E226775}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {433F961A-EFEA-4E51-ABD5-26B03E226775}.Debug|Any CPU.Build.0 = Debug|Any CPU + {433F961A-EFEA-4E51-ABD5-26B03E226775}.Release|Any CPU.ActiveCfg = Release|Any CPU + {433F961A-EFEA-4E51-ABD5-26B03E226775}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal From 65099138945bae6011b450874c1646416062afcf Mon Sep 17 00:00:00 2001 From: babisque Date: Mon, 27 May 2024 21:41:39 -0300 Subject: [PATCH 2/2] tests warnings are fixed now and the git workflow is updated --- .github/workflows/dotnet.yml | 3 +++ Catalog/Catalog.Test/ProductControllerTests.cs | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7e72cc0..1c6d654 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,3 +26,6 @@ jobs: - name: Build run: dotnet build --no-restore working-directory: ./Catalog/ + - name: Test + run: dotnet test --no-build --verbosity normal + working-directory: ./Catalog/ \ No newline at end of file diff --git a/Catalog/Catalog.Test/ProductControllerTests.cs b/Catalog/Catalog.Test/ProductControllerTests.cs index 5777130..a65d9eb 100644 --- a/Catalog/Catalog.Test/ProductControllerTests.cs +++ b/Catalog/Catalog.Test/ProductControllerTests.cs @@ -141,7 +141,7 @@ public async Task GetProduct_NonExistingId_ReturnsNotFound() { // Arrange _productRepositoryMock.Setup(repo => repo.GetByIdAsync(1)) - .ReturnsAsync((Product)null); + .ReturnsAsync((Product)null!); // Act var result = await _controller.GetProduct(1); @@ -196,7 +196,7 @@ public async Task Delete_NonExistingId_ReturnsNotFound() { // Arrange _productRepositoryMock.Setup(repo => repo.GetByIdAsync(1)) - .ReturnsAsync((Product)null); + .ReturnsAsync((Product)null!); // Act var result = await _controller.Delete(1);