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

时间:2013-10-23 12:19:56

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

我有以下方法:

Void UpdateUser(User user){}

我需要检查这个方法是否能正常工作。

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

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

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

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

5 个答案:

答案 0 :(得分:2)

模拟意味着您开发软件组件(类)的方式是将任何具有行为的类作为接口(或抽象类)使用/使用/调用。你编程为抽象。运行时使用某些东西(服务定位器,DI容器,工厂......)来检索/创建这些实例。

最常见的方法是使用构造注入Here是一个很好的解释,为什么人们会使用DI,以及如何使用DI的例子。

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

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

希望这会有所帮助。有很多来源可以找到。就个人而言,我刚刚阅读this book,我发现它非常好。 This是作者博客。

答案 1 :(得分:0)

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

你可以使用模拟框架,如moq,rhino等.moq非常简单,你可以找到许多例子来展示moq与DI一样的统一框架。

答案 2 :(得分:0)

如果你的课程是这样的

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  

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

答案 3 :(得分:0)

  

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

尽管他们有经验,但那些人都错了。出于某种原因,单元测试关于单独测试代码部分的错误观念近年来越来越受欢迎。实际上,单元测试就是编写作为一个单元的测试,换句话说,它们是孤立存在的,一个单元测试的结果不会影响另一个测试。

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

为了大大简化您的测试,您可以在UpdateUser和EF之间设置一个外推层。换句话说,UpdateUser类提供了一个接口实例,它是进入EF的网关。它没有直接与EF交谈。然后,模拟EF,您只需提供一个模拟的接口实现。然后,这就需要将EF测试到更基本的层,并采用更基本的CRUD行为。

答案 4 :(得分:-1)

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