diff --git a/Directory.Packages.props b/Directory.Packages.props index 8219f8c18..1b4d7fc1e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -23,7 +23,7 @@ - + @@ -40,6 +40,8 @@ + + @@ -59,7 +61,6 @@ all runtime; build; native; contentfiles; analyzers - diff --git a/tests/IntegrationTests/IntegrationTests.csproj b/tests/IntegrationTests/IntegrationTests.csproj index 5876dc3f9..0923dc669 100644 --- a/tests/IntegrationTests/IntegrationTests.csproj +++ b/tests/IntegrationTests/IntegrationTests.csproj @@ -8,9 +8,13 @@ - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + all runtime; build; native; contentfiles; analyzers diff --git a/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/AddItemToBasket.cs b/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/AddItemToBasket.cs index 9f1111469..75e1744ef 100644 --- a/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/AddItemToBasket.cs +++ b/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/AddItemToBasket.cs @@ -1,9 +1,10 @@ using System.Threading.Tasks; using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; +using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate; using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.ApplicationCore.Services; using Microsoft.eShopWeb.ApplicationCore.Specifications; -using Moq; +using NSubstitute; using Xunit; namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests; @@ -11,34 +12,35 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTes public class AddItemToBasket { private readonly string _buyerId = "Test buyerId"; - private readonly Mock> _mockBasketRepo = new(); - private readonly Mock> _mockLogger = new(); + private readonly IRepository _mockBasketRepo = Substitute.For>(); + private readonly IAppLogger _mockLogger = Substitute.For>(); [Fact] public async Task InvokesBasketRepositoryGetBySpecAsyncOnce() { var basket = new Basket(_buyerId); - basket.AddItem(1, It.IsAny(), It.IsAny()); - _mockBasketRepo.Setup(x => x.FirstOrDefaultAsync(It.IsAny(), default)).ReturnsAsync(basket); + basket.AddItem(1, 1.5m); - var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object); + _mockBasketRepo.FirstOrDefaultAsync(Arg.Any(), default).Returns(basket); + + var basketService = new BasketService(_mockBasketRepo, _mockLogger); await basketService.AddItemToBasket(basket.BuyerId, 1, 1.50m); - _mockBasketRepo.Verify(x => x.FirstOrDefaultAsync(It.IsAny(), default), Times.Once); + await _mockBasketRepo.Received().FirstOrDefaultAsync(Arg.Any(), default); } [Fact] public async Task InvokesBasketRepositoryUpdateAsyncOnce() { var basket = new Basket(_buyerId); - basket.AddItem(1, It.IsAny(), It.IsAny()); - _mockBasketRepo.Setup(x => x.FirstOrDefaultAsync(It.IsAny(), default)).ReturnsAsync(basket); + basket.AddItem(1, 1.1m, 1); + _mockBasketRepo.FirstOrDefaultAsync(Arg.Any(), default).Returns(basket); - var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object); + var basketService = new BasketService(_mockBasketRepo, _mockLogger); await basketService.AddItemToBasket(basket.BuyerId, 1, 1.50m); - _mockBasketRepo.Verify(x => x.UpdateAsync(basket, default), Times.Once); + await _mockBasketRepo.Received().UpdateAsync(basket, default); } } diff --git a/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/DeleteBasket.cs b/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/DeleteBasket.cs index cd94c3a04..0856d3d2a 100644 --- a/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/DeleteBasket.cs +++ b/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/DeleteBasket.cs @@ -2,7 +2,8 @@ using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.ApplicationCore.Services; -using Moq; +//using Moq; +using NSubstitute; using Xunit; namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests; @@ -10,21 +11,21 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTes public class DeleteBasket { private readonly string _buyerId = "Test buyerId"; - private readonly Mock> _mockBasketRepo = new(); - private readonly Mock> _mockLogger = new(); + private readonly IRepository _mockBasketRepo = Substitute.For>(); + private readonly IAppLogger _mockLogger = Substitute.For>(); [Fact] public async Task ShouldInvokeBasketRepositoryDeleteAsyncOnce() { var basket = new Basket(_buyerId); - basket.AddItem(1, It.IsAny(), It.IsAny()); - basket.AddItem(2, It.IsAny(), It.IsAny()); - _mockBasketRepo.Setup(x => x.GetByIdAsync(It.IsAny(), default)) - .ReturnsAsync(basket); - var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object); + basket.AddItem(1, 1.1m, 1); + basket.AddItem(2, 1.1m, 1); + _mockBasketRepo.GetByIdAsync(Arg.Any(), default) + .Returns(basket); + var basketService = new BasketService(_mockBasketRepo, _mockLogger); - await basketService.DeleteBasketAsync(It.IsAny()); + await basketService.DeleteBasketAsync(1); - _mockBasketRepo.Verify(x => x.DeleteAsync(It.IsAny(), default), Times.Once); + await _mockBasketRepo.Received().DeleteAsync(Arg.Any(), default); } } diff --git a/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/TransferBasket.cs b/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/TransferBasket.cs index c82c18d26..a21afb319 100644 --- a/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/TransferBasket.cs +++ b/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/TransferBasket.cs @@ -4,7 +4,7 @@ using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.ApplicationCore.Services; using Microsoft.eShopWeb.ApplicationCore.Specifications; -using Moq; +using NSubstitute; using Xunit; namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests; @@ -15,20 +15,36 @@ public class TransferBasket private readonly string _existentAnonymousBasketBuyerId = "existent-anonymous-basket-buyer-id"; private readonly string _nonexistentUserBasketBuyerId = "newuser@microsoft.com"; private readonly string _existentUserBasketBuyerId = "testuser@microsoft.com"; - private readonly Mock> _mockBasketRepo = new(); - private readonly Mock> _mockLogger = new(); + private readonly IRepository _mockBasketRepo = Substitute.For>(); + private readonly IAppLogger _mockLogger = Substitute.For>(); - [Fact] + public class Results + { + private readonly Queue> values = new Queue>(); + public Results(T result) { values.Enqueue(() => result); } + public Results Then(T value) { return Then(() => value); } + public Results Then(Func value) + { + values.Enqueue(value); + return this; + } + public T Next() { return values.Dequeue()(); } + } + + [Fact] public async Task InvokesBasketRepositoryFirstOrDefaultAsyncOnceIfAnonymousBasketNotExists() { - var anonymousBasket = null as Basket; - var userBasket = new Basket(_existentUserBasketBuyerId); - _mockBasketRepo.SetupSequence(x => x.FirstOrDefaultAsync(It.IsAny(), default)) - .ReturnsAsync(anonymousBasket) - .ReturnsAsync(userBasket); - var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object); + var anonymousBasket = null as Basket; + var userBasket = new Basket(_existentUserBasketBuyerId); + + var results = new Results(anonymousBasket) + .Then(userBasket); + + + _mockBasketRepo.FirstOrDefaultAsync(Arg.Any(), default).Returns(x => results.Next()); + var basketService = new BasketService(_mockBasketRepo, _mockLogger); await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId); - _mockBasketRepo.Verify(x => x.FirstOrDefaultAsync(It.IsAny(), default), Times.Once); + await _mockBasketRepo.Received().FirstOrDefaultAsync(Arg.Any(), default); } [Fact] @@ -40,12 +56,15 @@ public async Task TransferAnonymousBasketItemsWhilePreservingExistingUserBasketI var userBasket = new Basket(_existentUserBasketBuyerId); userBasket.AddItem(1, 10, 4); userBasket.AddItem(2, 99, 3); - _mockBasketRepo.SetupSequence(x => x.FirstOrDefaultAsync(It.IsAny(), default)) - .ReturnsAsync(anonymousBasket) - .ReturnsAsync(userBasket); - var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object); + + var results = new Results(anonymousBasket) + .Then(userBasket); + + _mockBasketRepo.FirstOrDefaultAsync(Arg.Any(), default).Returns(x => results.Next()); + var basketService = new BasketService(_mockBasketRepo, _mockLogger); await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId); - _mockBasketRepo.Verify(x => x.UpdateAsync(userBasket, default), Times.Once); + await _mockBasketRepo.Received().UpdateAsync(userBasket, default); + Assert.Equal(3, userBasket.Items.Count); Assert.Contains(userBasket.Items, x => x.CatalogItemId == 1 && x.UnitPrice == 10 && x.Quantity == 5); Assert.Contains(userBasket.Items, x => x.CatalogItemId == 2 && x.UnitPrice == 99 && x.Quantity == 3); @@ -57,13 +76,15 @@ public async Task RemovesAnonymousBasketAfterUpdatingUserBasket() { var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId); var userBasket = new Basket(_existentUserBasketBuyerId); - _mockBasketRepo.SetupSequence(x => x.FirstOrDefaultAsync(It.IsAny(), default)) - .ReturnsAsync(anonymousBasket) - .ReturnsAsync(userBasket); - var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object); + + var results = new Results(anonymousBasket) + .Then(userBasket); + + _mockBasketRepo.FirstOrDefaultAsync(Arg.Any(), default).Returns(x => results.Next()); + var basketService = new BasketService(_mockBasketRepo, _mockLogger); await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId); - _mockBasketRepo.Verify(x => x.UpdateAsync(userBasket, default), Times.Once); - _mockBasketRepo.Verify(x => x.DeleteAsync(anonymousBasket, default), Times.Once); + await _mockBasketRepo.Received().UpdateAsync(userBasket, default); + await _mockBasketRepo.Received().DeleteAsync(anonymousBasket, default); } [Fact] @@ -71,11 +92,13 @@ public async Task CreatesNewUserBasketIfNotExists() { var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId); var userBasket = null as Basket; - _mockBasketRepo.SetupSequence(x => x.FirstOrDefaultAsync(It.IsAny(), default)) - .ReturnsAsync(anonymousBasket) - .ReturnsAsync(userBasket); - var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object); + + var results = new Results(anonymousBasket) + .Then(userBasket); + + _mockBasketRepo.FirstOrDefaultAsync(Arg.Any(), default).Returns(x => results.Next()); + var basketService = new BasketService(_mockBasketRepo, _mockLogger); await basketService.TransferBasketAsync(_existentAnonymousBasketBuyerId, _nonexistentUserBasketBuyerId); - _mockBasketRepo.Verify(x => x.AddAsync(It.Is(x => x.BuyerId == _nonexistentUserBasketBuyerId), default), Times.Once); + await _mockBasketRepo.Received().AddAsync(Arg.Is(x => x.BuyerId == _nonexistentUserBasketBuyerId), default); } } diff --git a/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs index d2e342ac0..009bc84ea 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs @@ -2,7 +2,7 @@ using System.Linq; using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; using Microsoft.eShopWeb.ApplicationCore.Specifications; -using Moq; +using NSubstitute; using Xunit; namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications; @@ -58,18 +58,18 @@ public void MatchesNoBasketsIfBuyerIdNotPresent() public List GetTestBasketCollection() { - var basket1Mock = new Mock(_buyerId); - basket1Mock.SetupGet(s => s.Id).Returns(1); - var basket2Mock = new Mock(_buyerId); - basket2Mock.SetupGet(s => s.Id).Returns(2); - var basket3Mock = new Mock(_buyerId); - basket3Mock.SetupGet(s => s.Id).Returns(_testBasketId); + var basket1Mock = Substitute.For(_buyerId); + basket1Mock.Id.Returns(1); + var basket2Mock = Substitute.For(_buyerId); + basket2Mock.Id.Returns(2); + var basket3Mock = Substitute.For(_buyerId); + basket3Mock.Id.Returns(_testBasketId); return new List() { - basket1Mock.Object, - basket2Mock.Object, - basket3Mock.Object + basket1Mock, + basket2Mock, + basket3Mock }; } } diff --git a/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs index 32583222a..f9fc04941 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.eShopWeb.ApplicationCore.Entities; -using Moq; +using NSubstitute; using Xunit; namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications; @@ -36,14 +36,14 @@ private List GetTestCollection() { var catalogItems = new List(); - var mockCatalogItem1 = new Mock(1, 1, "Item 1 description", "Item 1", 1.5m, "Item1Uri"); - mockCatalogItem1.SetupGet(x => x.Id).Returns(1); + var mockCatalogItem1 = Substitute.For(1, 1, "Item 1 description", "Item 1", 1.5m, "Item1Uri"); + mockCatalogItem1.Id.Returns(1); - var mockCatalogItem3 = new Mock(3, 3, "Item 3 description", "Item 3", 3.5m, "Item3Uri"); - mockCatalogItem3.SetupGet(x => x.Id).Returns(3); + var mockCatalogItem3 = Substitute.For(3, 3, "Item 3 description", "Item 3", 3.5m, "Item3Uri"); + mockCatalogItem3.Id.Returns(3); - catalogItems.Add(mockCatalogItem1.Object); - catalogItems.Add(mockCatalogItem3.Object); + catalogItems.Add(mockCatalogItem1); + catalogItems.Add(mockCatalogItem3); return catalogItems; } diff --git a/tests/UnitTests/Builders/BasketBuilder.cs b/tests/UnitTests/Builders/BasketBuilder.cs index 08dd04a44..708df646c 100644 --- a/tests/UnitTests/Builders/BasketBuilder.cs +++ b/tests/UnitTests/Builders/BasketBuilder.cs @@ -1,5 +1,5 @@ using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; -using Moq; +using NSubstitute; namespace Microsoft.eShopWeb.UnitTests.Builders; @@ -22,17 +22,17 @@ public Basket Build() public Basket WithNoItems() { - var basketMock = new Mock(BasketBuyerId); - basketMock.SetupGet(s => s.Id).Returns(BasketId); + var basketMock = Substitute.For(BasketBuyerId); + basketMock.Id.Returns(BasketId); - _basket = basketMock.Object; + _basket = basketMock; return _basket; } public Basket WithOneBasketItem() { - var basketMock = new Mock(BasketBuyerId); - _basket = basketMock.Object; + var basketMock = Substitute.For(BasketBuyerId); + _basket = basketMock; _basket.AddItem(2, 3.40m, 4); return _basket; } diff --git a/tests/UnitTests/MediatorHandlers/OrdersTests/GetMyOrders.cs b/tests/UnitTests/MediatorHandlers/OrdersTests/GetMyOrders.cs index e0bd0038f..ccb4129cf 100644 --- a/tests/UnitTests/MediatorHandlers/OrdersTests/GetMyOrders.cs +++ b/tests/UnitTests/MediatorHandlers/OrdersTests/GetMyOrders.cs @@ -5,23 +5,22 @@ using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate; using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.Web.Features.MyOrders; -using Moq; +using NSubstitute; using Xunit; namespace Microsoft.eShopWeb.UnitTests.MediatorHandlers.OrdersTests; public class GetMyOrders { - private readonly Mock> _mockOrderRepository; + private readonly IReadRepository _mockOrderRepository = Substitute.For>(); public GetMyOrders() { var item = new OrderItem(new CatalogItemOrdered(1, "ProductName", "URI"), 10.00m, 10); - var address = new Address(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()); + var address = new Address("", "", "", "", ""); Order order = new Order("buyerId", address, new List { item }); - - _mockOrderRepository = new Mock>(); - _mockOrderRepository.Setup(x => x.ListAsync(It.IsAny>(), default)).ReturnsAsync(new List { order }); + + _mockOrderRepository.ListAsync(Arg.Any>(), default).Returns(new List { order }); } [Fact] @@ -29,7 +28,7 @@ public async Task NotReturnNullIfOrdersArePresIent() { var request = new eShopWeb.Web.Features.MyOrders.GetMyOrders("SomeUserName"); - var handler = new GetMyOrdersHandler(_mockOrderRepository.Object); + var handler = new GetMyOrdersHandler(_mockOrderRepository); var result = await handler.Handle(request, CancellationToken.None); diff --git a/tests/UnitTests/MediatorHandlers/OrdersTests/GetOrderDetails.cs b/tests/UnitTests/MediatorHandlers/OrdersTests/GetOrderDetails.cs index aa19b8348..625de042b 100644 --- a/tests/UnitTests/MediatorHandlers/OrdersTests/GetOrderDetails.cs +++ b/tests/UnitTests/MediatorHandlers/OrdersTests/GetOrderDetails.cs @@ -6,24 +6,23 @@ using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.ApplicationCore.Specifications; using Microsoft.eShopWeb.Web.Features.OrderDetails; -using Moq; +using NSubstitute; using Xunit; namespace Microsoft.eShopWeb.UnitTests.MediatorHandlers.OrdersTests; public class GetOrderDetails { - private readonly Mock> _mockOrderRepository; - + private readonly IReadRepository _mockOrderRepository = Substitute.For>(); + public GetOrderDetails() { var item = new OrderItem(new CatalogItemOrdered(1, "ProductName", "URI"), 10.00m, 10); - var address = new Address(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()); + var address = new Address("", "", "", "", ""); Order order = new Order("buyerId", address, new List { item }); - - _mockOrderRepository = new Mock>(); - _mockOrderRepository.Setup(x => x.FirstOrDefaultAsync(It.IsAny(), default)) - .ReturnsAsync(order); + + _mockOrderRepository.FirstOrDefaultAsync(Arg.Any(), default) + .Returns(order); } [Fact] @@ -31,7 +30,7 @@ public async Task NotBeNullIfOrderExists() { var request = new eShopWeb.Web.Features.OrderDetails.GetOrderDetails("SomeUserName", 0); - var handler = new GetOrderDetailsHandler(_mockOrderRepository.Object); + var handler = new GetOrderDetailsHandler(_mockOrderRepository); var result = await handler.Handle(request, CancellationToken.None); diff --git a/tests/UnitTests/UnitTests.csproj b/tests/UnitTests/UnitTests.csproj index 4b069f28c..c2d6e0c8b 100644 --- a/tests/UnitTests/UnitTests.csproj +++ b/tests/UnitTests/UnitTests.csproj @@ -10,7 +10,11 @@ - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive +