使用EF或Linq的任何点单元测试方法

本文关键字:任何点 单元 测试方法 Linq EF 使用 | 更新日期: 2023-09-27 18:00:12

我正在为我的服务层编写单元测试,我完全明白了创建单元测试来验证逻辑的意义。例如,如果我创建了一个添加两个数字的函数,那么一定要为此编写一个单元测试。

但如果在我的服务层方法中,我有这样的

public ICollection<MyEntity> GetAll()
{
    return _context.MyEntities
        .Where(e => !e.IsDeleted)
        .ToList();
}

单元测试有什么意义?既然我是从数据库中得到的,那么嘲笑数据库似乎很愚蠢,因为我只是假设Linq正在正常工作?

用一个包含相同数据的实际"测试"数据库来测试这一点不是更好吗?这样我就可以看到从数据库中检索到的记录数量是否符合我的预期?

我知道对数据库的测试使这更像是一个集成测试,但它真的适用于单元测试吗?

如果我举另一个例子,比如这个

public int Delete(long id)
{
    _context.Database.ExecuteCommand("DELETE FROM myTable WHERE Id = ?", id);
    return _context.SaveChanges();
}

如何对该功能进行单元测试?如果我模拟_context.Database并创建一个单元测试来检查是否调用了_context.SaveChanges(我认为这没有任何意义),那么就无法保证它会真正删除我的数据。如果我有外键约束怎么办?mock会通过,但实际的方法真的会失败吗?

我刚开始想,除非一个方法真的计算出某种逻辑,否则我看不出创建单元测试的意义/原因,尤其是在使用实体框架时?

使用EF或Linq的任何点单元测试方法

我认为对几乎所有类型的函数进行单元测试是有意义的:

"单元测试有什么意义?因为我是从数据库中得到的,所以嘲笑数据库似乎很愚蠢,因为我只是假设Linq正在正常工作?"

  • 您不是在测试Linq,而是在测试函数;该函数的名称为CCD_ 1;我可以简单地假设这将返回数据库中存储的所有CCD_ 2实例。但它只是简单地返回已删除的项目;单元测试不仅仅是验证功能是否正常工作;这也是检查此函数是否正确命名的一种方法
  • 这个函数也有问题;如果

    _context.MyEntities(e=>!e.IsDeleted)是否返回null?ToList将引发异常。然后,如果您测试极值,单元测试将有助于识别潜在的问题。

  • 此外,单元测试迫使您使用抽象。如果你不能对一个方法进行单元测试,该方法可能会出现问题,你需要调查该方法并重新考虑。

    _context.Database.ExecuteCommand("DELETE FROM myTable WHERE Id=?",Id);在我看来,这行代码需要留在其他地方,而不是在服务层(可能在存储库中?)。如果id是"-1"怎么办?你将如何处理这个异常?

我认为很难说明一个关于不包括Linq的单元测试方法的通用规则。

为什么要对添加两个数字的函数进行单元测试?与测试LINQ或EF相比,您没有测试+运算符。你正在测试行为,所以测试你可能认为"只是有效的"的事情是完全有效的。例如,如果我禁止在你的应用程序中使用EF,你仍然需要一个测试来确保你用什么来替换函数的正确性。

你想在哪里划线?

对于与数据库相关的代码,我实际上会针对真实的数据库而不是mock进行测试。这是确保SQL有效的唯一方法(无论是手工编写还是让ORM为您生成)。有一些工具可以让这变得更容易,比如《重生》。

相关文章: