我如何测试具有Db上下文和记录器的Asp.Net Core控制器?

问题描述 投票:0回答:1

我有一个带有两个参数的控制器,需要通过单元测试对其进行测试。想测试4个参数,例如ViewBug等。但是我如何制作假的数据库上下文和记录器呢?我现在被困住了:

        [Fact]
    public void IndexReturnsAViewResultWithAListOfUsers()
    {
        // Arrange
        var mock = new Mock<AircraftsController>();
        var controller = new AircraftsController(/*params*/);

        // Act

        // Assert
    }

这是我的控制器:

 public class AircraftsController : Controller
{
    #region DbContext, Logger
    public AppDbContext Context { get; }
    private readonly ILogger<AircraftsController> _logger;

    public AircraftsController(AppDbContext context, ILogger<AircraftsController> logger)
    {
        Context = context;      
        _logger = logger;
        _logger.LogDebug(1, "NLog injected into Controller");
    }
    #endregion



    [HttpGet]
    public IActionResult Compare(int vehicle1, int vehicle2, int vehicle3, int vehicle4)
    {
        var planesFromDb = Context.Planes.OrderBy(x => x.BR).ToList();
        planesFromDb.Insert(0, new Plane { Image = "~/images/EmptyPlane.png", Nation = "EmptyFlag", Name = "Select aircraft", VehicleId=0 });
        var selectedPlanes = new List<Plane>();
        ViewBag.AllPlanesSelected = planesFromDb;

        selectedPlanes.Add(planesFromDb.FirstOrDefault(p => p.VehicleId == vehicle1));
        selectedPlanes.Add(planesFromDb.FirstOrDefault(p => p.VehicleId == vehicle2));
        selectedPlanes.Add(planesFromDb.FirstOrDefault(p => p.VehicleId == vehicle3));
        selectedPlanes.Add(planesFromDb.FirstOrDefault(p => p.VehicleId == vehicle4));

        _logger.LogInformation("Log Message");

        return View(selectedPlanes);
    }

}
unit-testing asp.net-core moq xunit
1个回答
0
投票

在.NET Core中,您可以利用内存数据库进行单元测试。有两个选项,EF内存数据库和SQLite内存数据库。我更喜欢SQLite内存,因为与EF内存不同,它为您提供了处理关系数据的所有优点。

Testing with the EF In-Memory Database

SQLite In-Memory Database

以下是使用SQLite内存数据库进行单元测试的简单实现:

    public YourContext GetDbContext()
    {
        var connection = new SqliteConnection("DataSource=:memory:");
        connection.Open();

        var option = new DbContextOptionsBuilder<YourContext>()
            .UseSqlite(connection,
            s => {
                s.UseNetTopologySuite();
                s.MigrationsHistoryTable("__MigrationHistory");
            }).Options;

        var dbContext = new YourContext(option);

        //Added to recreate database and run migration for each test.
        if (dbContext != null)   
        {
            dbContext.Database.EnsureDeleted();
            dbContext.Database.EnsureCreated();
        }

        return dbContext;
    }

然后在单元测试中:

var context = GetDbContext();

或者,您可以将GetDbContext方法放在固定装置中,这样,每个测试类仅一次创建数据库。在固定装置中有一个dispose方法来运行dbContext.Database.EnsureDeleted()来清理测试类之间的数据。

Shared context between Tests - Class Fixtures

© www.soinside.com 2019 - 2024. All rights reserved.