2008-11-21 107 views
24

之前我问过这个问题How to correctly unit test my DAL?,有一件事情没有给我答案,如果要真正测试我的DAL是有一个测试数据库,那么模拟与测试数据库有什么作用?嘲笑与测试数据库?

为了补充说明,另一个人建议“在单元测试结束时使用事务和回滚,因此db是干净的”,测试db。你们认为这个测试+测试DB +事务回滚(所以db没有真正写入),测试DAL的方法是什么?

为了完整,我的DAL使用实体框架构建,数据库中没有存储过程。由于EF非常新,我真的需要测试DAL以确保它们正常工作。

回答

13

我想你可能会想要做一些集成测试来检查由你的数据库结构强制执行的逻辑,例如约束,触发器,自动增量列等等。然而,你应该对单元测试模拟出任何框架你想要的DAL依赖的组件(在你的单元测试中)只测试你编码的那些组件。您并不需要在SqlCommand或SqlConnection上测试方法(例如)。您应该假设您使用的框架组件工作并为它们创建存根或嘲笑,将已知数据(好的,坏的,异常)返回给您的方法,以确保您的方法正常工作。不用嘲笑你负责在数据库中生成数据并确保它是正确的。您还会在网络,数据库本身等上留下开放的依赖关系,这可能会让您的测试变得脆弱。

此外,单元测试不会消除其他类型测试的需要。集成测试和验收测试仍然有效,需要完成。他们可能不需要像单元测试那样使用相同的频率来完成,并且可能不需要像单元测试那样提高代码质量,但单元测试不是一个神奇的子弹。

0

通过使用测试数据库,您可能会在数据库本身或DAL和数据库之间的通信路径(网络等)中引发问题。嘲笑消除了这些可能性。

+0

有人建议用test db做事务和回滚,你怎么看待这种测试DAL的方法? – 2008-11-21 21:46:35

+0

根据我的经验,交易和回滚一直很慢。 – y0mbo 2008-11-21 21:51:39

7

当测试数据访问代码时,我没有发现嘲笑非常有用。单元测试的目的是验证与数据库相关的代码工作,并嘲笑数据库会阻碍测试。

测试业务代码时,Mocking确实变得有用。您可以模拟您的数据库调用以返回测试数据,并在这些情况下验证业务逻辑的行为。

关于事务的使用 - 这当然是可能的,只要您的架构在测试开始时有足够空间启动事务,然后在该事务内部进行所有与数据库相关的单元测试调用。虽然从未尝试过。

1

我们使用了事务性单元测试,并且多次阻止了Hibernate映射问题。否则 - 单元测试是什么?一些微不足道的东西,如List<Item> getAllItems()? :)

2

把单元测试放入回滚声音hacky的交易。 而不是我在测试运行之前(即在我的测试类的构造函数中)清除任何crud(即不是静态/引用数据)的数据库的代码。当您的测试失败时,它有助于让数据仍在数据库中,以检查失败的原因。

0

这不仅是您必须考虑的数据库的状态,它也是可用性。如果您的数据库处于脱机状态,那么您的所有DAL测试都应该失败?

您需要测试的是您的DAL发出正确的命令以创建/检索/更新/删除。您不需要为此执行SQL,只需使用对象持久性框架并检查是否给出了正确的说明。

-1

这个问题很可能在原来的问题。

public class MusicStoreEntities : DbContext 
    { 
     public DbSet<Album> Albums { get; set; } 
     public DbSet<Genre> Genres { get; set; } 
     public DbSet<Artist> Artists { get; set; } 
     public DbSet<Cart> Carts { get; set; } 
     public DbSet<Order> Orders { get; set; } 
     public DbSet<OrderDetail> OrderDetails { get; set; } 
    } 

对我来说这紧密结合的持久性的实现,我认为这是一件坏事:有些MVC比较流行的例子返回一个DbSet如使用快捷方式。它会更好地返回List<t>这可能很容易被嘲笑。

0

不只是测试你的应用程序。您还在测试您的配置以及您的存储过程和视图。这些记录在你的单元测试中。