如何为更改数据的方法编写单元测试

本文关键字:方法 单元测试 数据 | 更新日期: 2023-09-27 18:36:44

>我有以下方法:

Void UpdateUser(User user){}

我需要检查此方法是否正常工作。

我在单元测试中使用了一个单独的数据库来检查这一点。但是很多有经验的人说,如果我用这种方法,那不会是单元测试;这就是集成测试。

但是我不知道如何模拟单元测试。

UpdateUser 方法中编写的代码将尝试使用实体框架更新数据。

如果我嘲笑(实际上我也不知道如何做到这一点),这将如何与实体框架一起使用?

如何为更改数据的方法编写单元测试

模拟意味着你开发软件组件(类)的方式是,任何具有行为的类都被使用/消费/调用为接口(或抽象类)。你编程到一个抽象。运行时,您使用某些内容(服务定位器、DI 容器、工厂等)来检索/创建这些实例。

最常见的方法是使用施工注入。以下是为什么使用 DI 的出色解释,以及如何执行此操作的示例。

在您的情况下,使用实体框架的组件(例如存储库)必须实现存储库接口,并且使用存储库的任何类都应将其用作接口。

这样,您就可以在单元测试中模拟存储库。这意味着您创建一个单元测试存储库类(与任何数据库或 EF 无关),并在创建要进行单元测试的类的实例时使用它。

希望这有所帮助。有许多来源可以找到。就我个人而言,我刚刚读了这本书,我发现它非常好。这是作者的博客。

您可以使用事务和回滚或创建测试用户尝试其更新。断言,然后在最后块中删除测试用户。

您可以使用模拟框架,如最小起订量,犀牛等,起订量非常简单,您可以找到许多使用DI演示起订量的示例,例如unity框架。

如果你的类是这样的

public class UserRepository()
{
    Sqlcontext _context;
    void UpdateUser(User user)
    {
       _context.Users.Add(user);
    }
}

那么这是不可测试的。

虽然这不是单元测试,但如果您坚持连接数据库并对其进行测试,则可以将函数更改为

User UpdateUser(User user)
{
    _context.Users.Add(user);
    return user;
}

并测试是否

user.Id > 0  

在这里,您基本上只是在测试实体框架。

"我在单元测试中使用了一个单独的数据库来检查这一点。但是很多 有经验的人说如果我用这种方法,那不会是单位 测试;这就是集成测试。

那些人错了,尽管他们所谓的经历。出于某种原因,单元测试都是关于孤立地测试部分代码的错误观念近年来越来越流行。实际上,单元测试就是编写充当单元的测试,换句话说,它们是孤立存在的,一个单元测试的结果不会影响另一个测试。

如果 UpdateUser 方法直接访问 EF,则只要确保保证数据库在每个测试结束时回滚到其起始状态,就可以进行单元测试。但是,为每个测试设置数据库并确保它可以可靠地回滚可能需要很多工作。这就是为什么经常使用模拟的原因。其他答案已经涵盖了 mcoking EF,所以我不会一一一赘述。

为了大大简化测试,可以在 UpdateUser 和 EF 之间有一个外推层。换句话说,UpdateUser类提供了一个接口实例,该实例是其进入 EF 的网关。它不直接与 EF 通信。若要模拟 EF,只需提供接口的模拟实现。然后,这会将针对 EF 进行测试的需求向下推到更基本的层,具有更基本的类似 CRUD 的行为。

一个非官方的技巧,非最佳实践可能是在测试时使用内存数据库(上下文)。

使用事务并在测试结束时回滚事务