单元测试与集成测试:实体框架核心在内存中

时间:2017-11-01 13:47:11

标签: c# unit-testing asp.net-core entity-framework-core in-memory-database

我目前正在使用EF Core 2.0开发ASP.NET Core 2.0 Web API。我计划实现Repository + UnitOfWork模式,并且我已经创建了抽象,接口等。由于我遵循TDD方法,我想在继续执行之前在这些接口上编写测试。

我面临的问题主要与语义有关。我在我的解决方案中创建了两个项目,一个用于单元测试,一个用于集成测试。对我来说很明显,同样测试数据库的测试不是单元测试,因此应该放在IntegrationTests项目中。但事实是,我正在计划使用EntityFrameworkCore.InMemory提供程序,并为每个测试启动虚假的内存数据库。

所以每个测试都应该有这个结构:

[TestClass]
public class GamesRepositoryTest
{
    AppDbContext _context;
    IGamesRepository _repository;

    public GamesRepositoryTest()
    {

    }

    [TestInitialize]
    public void Initialize()
    {
        DbContextOptionsBuilder<AppDbContext> builder = new DbContextOptionsBuilder<AppDbContext>().UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString());
        _context = new AppDbContext(builder.Options);
        _repository = new GamesRepository(_context);
    }

    [TestCleanup]
    public void Cleanup()
    {
        _context.Database.EnsureDeleted();
    }
}

所以我的问题是,EntityFrameworkCore.InMemory是否提供了足够的抽象级别,以便上述类可以被视为单元测试,还是应该将它放在IntegrationTests项目中?

2 个答案:

答案 0 :(得分:13)

新的内存提供商将每个人的内容搞糊涂了。首先,让我们清理它的目的:它是一个测试数据提供者。就是这样。您可以轻松地模拟DbContext并返回静态列表或其他内容。内存提供程序只是为您提供了一种更简单的方法来设置该测试支架。它不适合集成测试,因为您实际上不会在生产中使用它。正确的集成测试将真正实现您的生产设置传真。

也就是说,实体框架核心的新内存提供商的主要问题是,现在人们似乎在滥用它来测试他们不应该测试的东西。 EF Core已经过充分测试,因此您只应测试您的应用程序代码。再一次,只要把它想象成一个没有实际设置模拟的模拟。只要你这样做,你应该没事。

基于这一切,为了回答你的问题,你的测试应该是单元测试,如果除了你实际创建集成测试之外没有其他原因,你不应该使用内存中供应商。只需确保 实际进行单元测试。

答案 1 :(得分:0)

如果您正在使用真正的dbContext进行测试,无论它是在点击RDBMS还是InMemory提供程序,它都是集成测试。为什么?因为您正在测试该框架的实现,而不是您的方法中运行的代码。单元测试只测试&#34;单元&#34;他们正在运行的代码,通常是单个方法(而不是其协作者)。

EF Core的InMemory提供程序与使用真实数据库进行测试不是100%相同。事实上,存在很多差异。它在开发时非常有用,可以显示系统如何使用某些种子数据以及可以验证整个系统是否按预期工作的功能测试(例如,使用TestServer)。

如果您的单元测试项目仅包含单元测试,那么它不应该依赖于基础架构特定的代码,如EF Core。它通常应该只依赖于您正在测试的项目,以及您为测试使用的任何工具(例如xUnit,Moq等)。如果您发现自己正在汲取基础架构依赖性,那么您可能正在编写集成测试。