【问题标题】:How to test EF Core project stand alone如何独立测试 EF Core 项目
【发布时间】:2023-02-01 18:16:15
【问题描述】:

我有一个解决方案,其中只有一个类库项目具有 EF Core 功能。该项目仅用于处理数据库。 API项目在不同的解决方案中。有什么办法单元测试这个项目是独立的,而不是来自 API 项目。

【问题讨论】:

  • 当然,只需创建一个使用该库的单元测试项目。它实际上是dotnet new xunitdotnet add reference ..。您面临的确切问题是什么?
  • @SergeyKudriavtsev 我将如何测试我的表和初始数据是否按预期存在于数据库中。
  • 是的。您可以在同一解决方案或不同的解决方案中创建单独的测试项目,并使用 xUnit 或 MSTest 等测试框架为您的类库编写和运行测试。在您的测试中,您可以模拟数据库上下文并设置测试数据以隔离类库的功能并验证它是否按预期运行。
  • @niler 关于数据,您有两个选择,都不是理想选择,但是...第一个是使用内存数据库上下文。只要您没有复杂的查询并且不依赖于例如,这就会起作用。具有级联操作的外键,因为内存数据库引擎非常有限。另一种选择是每次运行测试时启动一个新的本地数据库,用模拟数据填充它并将其用作测试的基础。这使您更接近生产,但涉及创建额外的设置和拆卸脚本。
  • 显然,您可以使用与实际(测试)数据库的连接,但这并不理想,因为它在逻辑上将您的单元测试转换为集成测试并损害了测试的可重复性。

标签: c# .net unit-testing entity-framework-core xunit


【解决方案1】:

XUnit 和 Moq 的简单示例:

public class ExampleDbContext : DbContext
{
    public DbSet<ExampleEntity> ExampleEntities { get; set; }

    public ExampleDbContext(DbContextOptions<ExampleDbContext> options) : base(options) { }
}

public class ExampleEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public interface IExampleRepository
{
    void Add(ExampleEntity entity);
    Task<ExampleEntity> Get(int id);
}

public class ExampleRepository : IExampleRepository
{
    private readonly ExampleDbContext _context;

    public ExampleRepository(ExampleDbContext context)
    {
        _context = context;
    }

    public void Add(ExampleEntity entity)
    {
        _context.ExampleEntities.Add(entity);
        _context.SaveChanges();
    }

    public Task<ExampleEntity> Get(int id)
    {
        return _context.ExampleEntities.FindAsync(id);
    }
}

public class ExampleRepositoryTests
{
    [Fact]
    public async Task TestGetMethod()
    {
        // Arrange
         var options = new DbContextOptionsBuilder<ExampleDbContext>()
            .UseInMemoryDatabase(databaseName: "TestDB")
            .Options;

         // Insert seed data into the database using one instance of the context
        using (var context = new ExampleDbContext(options))
        {
            context.ExampleEntities.Add(new ExampleEntity { Id = 1, Name = "Test Entity 1" });
            context.SaveChanges();
        }

        // Use a clean instance of the context to run the test
        using (var context = new ExampleDbContext(options))
        {
            var repository = new ExampleRepository(context);

            // Act
            var result = await repository.Get(1);

            // Assert
            Assert.Equal("Test Entity 1", result.Name);
        }
    }

    [Fact]
    public void TestAddMethod()
    {
        // Arrange
        var options = new DbContextOptionsBuilder<ExampleDbContext>()
            .UseInMemoryDatabase(databaseName: "TestDB")
            .Options;

        var mockContext = new Mock<ExampleDbContext>(options);
        var repository = new ExampleRepository(mockContext.Object);
        var entity = new ExampleEntity { Id = 2, Name = "Test Entity 2" };

        // Act
        repository.Add(entity);

        // Assert
        mockContext.Verify(c => c.ExampleEntities.Add(entity), Times.Once());
        mockContext.Verify(c => c.SaveChanges(), Times.Once());
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 2011-02-27
    相关资源
    最近更新 更多