简体   繁体   中英

How to xUnit Test an ASP.NET 5 with Sqlite

Using Microsoft.Data.Sqlite , it will try to locate the database file within the wwwroot directory by default of the ASP.NET 5 project(the Empty Template).

How to properly xUnit Test this kind of project? If I reference this ASP.NET project to my xUnit Test Project, it will surely use the directory of the xUnit Test Project as the base.

Update 1

I want to perform an integration testing using xUnit. Thanks for someone who clarified things to me.

The idea behind unit tests is to only test a certain functionality of a class without it's dependencies (like database, file system or network).

In order to achieve this you need to design your classes with Inversion of Control in mind and abstract necessary types into interfaces.

Imagine a OrdersService class that may get the number of orders or total sum of all orders and you want to test it's logic.

public interface IOrdersRepository 
{
    IEnumerable<Order> GetOrdersForCustomer(Guid customerId);
}

public class OrdersService : IOrdersService 
{
    private readonly IOrdersRepository ordersRepository;

    // pass the orders repository that abstracts the database access
    // as a dependency, so your OrdersService can be tested in isolation
    public OrdersService(IOrdersRepository ordersRepository)
    {
        this.ordersRepository = ordersRepository
    }

    public int GetOrdersCount(Customer customer) 
    {
        return ordersRepository.GetOrdersForCustomer(customer.Id).Count();
    }

    public decimal GetAllOrdersTotalSum(Customer customer)
    {
        return ordersRepository.GetOrdersForCustomer(customer.Id).Sum(order => order.TotalSum);
    }
}

Then in your unit test you'd do something like

[Fact]
public void CalculateOrderTotalSumTest() 
{
    // customer id we want to check 
    Guid customerId = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354");

    // Our test data
    List<Order> orders = new List<Order>()
    {
        new Order() { Customer = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354"), TotalSum = 100.0m),
        new Order() { Customer = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354"), TotalSum = 50.0m)
    }

    // Create a mock of the IOrdersRepository
    var ordersRepositoryMock = new Mock<IOrdersRepository>();
    // Next you need to set up the mock to return a certain value
    ordersRepositoryMock
        .Setup( m => m.ordersRepositoryMock(It.Is<Guid>( cId => cId == customerId) )
        .Returns(orders);

    decimal totalSum = ordersRepositoryMock.Object.GetAllOrdersTotalSum(customerId);
    Assert.AreEqual(150.0m, totalSum, "Total sum doesn't match expected result of 150.0m");
    ordersRepositoryMock.VerifyAll();
}

This way you can test your classes in isolation without the need of a database. If you need a database, a file on the filesystem or network connection in a unit test, then you have done bad job on designing your types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM