繁体   English   中英

模拟与测试数据库?

[英]Mocking vs. Test DB?

之前我问过这个问题如何正确单元测试我的DAL? ,有一件事对我来说没有答案是,如果真的测试我的DAL是有一个测试数据库,那么模拟与测试数据库的作用是什么?

另外,另一个人建议“在单元测试结束时使用事务和回滚,因此db是干净的”,测试db就是。 你们怎么看待这个测试+测试DB +事务回滚(所以db不是真正编写的)测试DAL的方法?

为了完整,我的DAL是使用Entity Framework构建的,DB中没有存储过程。 由于EF是如此新颖,我真的需要测试DAL以确保它们正常工作。

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

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

在测试数据访问代码时,我没有发现mocking非常有用。 单元测试的目的是验证与数据库相关的代码是否有效,并且模拟数据库会妨碍测试。

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

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

将单元测试放入回滚的交易中听起来很糟糕。 而不是我在测试运行之前(即在我的测试类的构造函数中)有代码清除任何crud的数据库(即任何非静态/引用数据)。 当测试失败时,有助于使数据仍在数据库中以检查失败的原因。

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

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

通过使用测试数据库,您可以在数据库本身或DAL与数据库之间的通信路径(网络等)上发生问题。 模拟消除了这些可能性。

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

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

问题很可能出现在最初的问题中。 一些比较流行的MVC示例通过返回DbSet使用快捷方式,例如:

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; }
    }

对我来说,这紧密地结合了持久性的实现,我认为这是一件坏事。 返回List<t>会更容易被嘲笑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM