-
-
Notifications
You must be signed in to change notification settings - Fork 220
Testing
Huy Nguyen edited this page Apr 5, 2025
·
2 revisions
This guide will help you understand how to write and run tests for Mixcore CMS applications.
Create a new test project:
dotnet new xunit -n MyModule.Tests
Add necessary NuGet packages:
dotnet add package Moq
dotnet add package FluentAssertions
dotnet add package Microsoft.EntityFrameworkCore.InMemory
public class ProductServiceTests
{
private readonly Mock<IProductRepository> _repositoryMock;
private readonly Mock<ILogger<ProductService>> _loggerMock;
private readonly ProductService _service;
public ProductServiceTests()
{
_repositoryMock = new Mock<IProductRepository>();
_loggerMock = new Mock<ILogger<ProductService>>();
_service = new ProductService(_repositoryMock.Object, _loggerMock.Object);
}
[Fact]
public async Task GetProductAsync_ExistingProduct_ReturnsProduct()
{
// Arrange
var product = new Product { Id = 1, Name = "Test Product" };
_repositoryMock.Setup(r => r.GetByIdAsync(1))
.ReturnsAsync(product);
// Act
var result = await _service.GetProductAsync(1);
// Assert
result.Should().NotBeNull();
result.Id.Should().Be(1);
result.Name.Should().Be("Test Product");
}
[Fact]
public async Task GetProductAsync_NonExistingProduct_ThrowsNotFoundException()
{
// Arrange
_repositoryMock.Setup(r => r.GetByIdAsync(1))
.ReturnsAsync((Product)null);
// Act & Assert
await Assert.ThrowsAsync<NotFoundException>(() =>
_service.GetProductAsync(1));
}
}
public class ProductsControllerTests
{
private readonly Mock<IProductService> _serviceMock;
private readonly ProductsController _controller;
public ProductsControllerTests()
{
_serviceMock = new Mock<IProductService>();
_controller = new ProductsController(_serviceMock.Object);
}
[Fact]
public async Task Get_ExistingProduct_ReturnsOk()
{
// Arrange
var product = new ProductDto { Id = 1, Name = "Test Product" };
_serviceMock.Setup(s => s.GetProductAsync(1))
.ReturnsAsync(product);
// Act
var result = await _controller.Get(1);
// Assert
var okResult = Assert.IsType<OkObjectResult>(result);
var returnedProduct = Assert.IsType<ProductDto>(okResult.Value);
returnedProduct.Id.Should().Be(1);
returnedProduct.Name.Should().Be("Test Product");
}
}
public class ProductIntegrationTests : IClassFixture<WebApplicationFactory<Startup>>
{
private readonly WebApplicationFactory<Startup> _factory;
private readonly HttpClient _client;
public ProductIntegrationTests(WebApplicationFactory<Startup> factory)
{
_factory = factory;
_client = _factory.CreateClient();
}
[Fact]
public async Task GetProduct_ReturnsProduct()
{
// Arrange
var productId = 1;
// Act
var response = await _client.GetAsync($"/api/products/{productId}");
// Assert
response.EnsureSuccessStatusCode();
var product = await response.Content.ReadAsAsync<ProductDto>();
product.Should().NotBeNull();
product.Id.Should().Be(productId);
}
}
public class ProductRepositoryTests
{
private readonly DbContextOptions<ApplicationDbContext> _options;
private readonly ApplicationDbContext _context;
public ProductRepositoryTests()
{
_options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "TestDb")
.Options;
_context = new ApplicationDbContext(_options);
}
[Fact]
public async Task AddProduct_ProductAddedSuccessfully()
{
// Arrange
var repository = new ProductRepository(_context);
var product = new Product { Name = "Test Product", Price = 10.99m };
// Act
await repository.AddAsync(product);
// Assert
var savedProduct = await _context.Products.FirstOrDefaultAsync();
savedProduct.Should().NotBeNull();
savedProduct.Name.Should().Be("Test Product");
}
}
public class ProductServiceTests
{
// MethodName_Scenario_ExpectedResult
[Fact]
public async Task GetProductAsync_ProductExists_ReturnsProduct()
{
// Test implementation
}
// MethodName_Scenario_ThrowsException
[Fact]
public async Task GetProductAsync_ProductNotFound_ThrowsNotFoundException()
{
// Test implementation
}
}
public class ProductServiceTests
{
public class GetProductAsync
{
[Fact]
public async Task ProductExists_ReturnsProduct()
{
// Test implementation
}
[Fact]
public async Task ProductNotFound_ThrowsNotFoundException()
{
// Test implementation
}
}
public class CreateProductAsync
{
[Fact]
public async Task ValidProduct_CreatesProduct()
{
// Test implementation
}
[Fact]
public async Task InvalidProduct_ThrowsValidationException()
{
// Test implementation
}
}
}
public class OrderServiceTests
{
private readonly Mock<IProductRepository> _productRepositoryMock;
private readonly Mock<IOrderRepository> _orderRepositoryMock;
private readonly Mock<IPaymentService> _paymentServiceMock;
private readonly OrderService _service;
public OrderServiceTests()
{
_productRepositoryMock = new Mock<IProductRepository>();
_orderRepositoryMock = new Mock<IOrderRepository>();
_paymentServiceMock = new Mock<IPaymentService>();
_service = new OrderService(
_productRepositoryMock.Object,
_orderRepositoryMock.Object,
_paymentServiceMock.Object);
}
[Fact]
public async Task PlaceOrder_ValidOrder_ProcessesSuccessfully()
{
// Arrange
var product = new Product { Id = 1, Price = 10.99m };
_productRepositoryMock.Setup(r => r.GetByIdAsync(1))
.ReturnsAsync(product);
_paymentServiceMock.Setup(s => s.ProcessPaymentAsync(It.IsAny<decimal>()))
.ReturnsAsync(new PaymentResult { Success = true });
// Act
var result = await _service.PlaceOrderAsync(new OrderRequest
{
ProductId = 1,
Quantity = 2
});
// Assert
result.Success.Should().BeTrue();
_orderRepositoryMock.Verify(r => r.AddAsync(It.IsAny<Order>()), Times.Once);
}
}
dotnet test
dotnet test --filter "FullyQualifiedName~ProductServiceTests"
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
Add test execution to your CI pipeline:
- name: Run Tests
run: dotnet test --no-restore --verbosity normal
- Visit our Community Forum
- Check the Troubleshooting Guide
- Contact Support for enterprise assistance