Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 使用两个数据库查询对方法进行单元测试。我应该取消数据库调用吗?轨道/Rspec_Ruby On Rails_Unit Testing_Rspec - Fatal编程技术网

Ruby on rails 使用两个数据库查询对方法进行单元测试。我应该取消数据库调用吗?轨道/Rspec

Ruby on rails 使用两个数据库查询对方法进行单元测试。我应该取消数据库调用吗?轨道/Rspec,ruby-on-rails,unit-testing,rspec,Ruby On Rails,Unit Testing,Rspec,我正在尝试测试一种方法,它可以适度地使用ActiveRecord。我一直听说单元测试方法和不使用数据库是最好的方法。然而,对我来说,这样做的缺点是,如果您错误地从ActiveRecord截取响应,会怎么样?我可能错误地删除了ActiveRecord在现实中返回的任何内容,现在我有了一个不准确的测试 仅供参考一个用户有很多优惠券,一张优惠券可以有很多优惠券。当它应用于一个订单时,用户可以使用这些优惠券 这是我的方法: def get_coupons_and_uses_for_user

我正在尝试测试一种方法,它可以适度地使用ActiveRecord。我一直听说单元测试方法和不使用数据库是最好的方法。然而,对我来说,这样做的缺点是,如果您错误地从ActiveRecord截取响应,会怎么样?我可能错误地删除了ActiveRecord在现实中返回的任何内容,现在我有了一个不准确的测试

仅供参考一个用户有很多优惠券,一张优惠券可以有很多优惠券。当它应用于一个订单时,用户可以使用这些优惠券

这是我的方法:

def get_coupons_and_uses_for_user
      coupons = Promotions::Coupon
        .includes(:coupon_uses)
        .where(user_id: user_id)

      coupons.reduce([]) do |memo, c|
        memo << { coupon: c, coupon_uses: c.coupon_uses.order('created_at desc') }
      end
    end
这是测试的好方法吗?或者我应该使用数据库?为什么

这里的问题是,我正在按如下方式删除ActiveRecord调用的返回值:

allow(coupon1).to receive_message_chain(:coupon_uses, :order) { [coupon_use1, coupon_use2] }

但是如果我对查询返回的内容有错误,那该怎么办?想象一下,如果查询更复杂。这是一个有效的问题吗?

否,不要将呼叫存根到数据库

Rails惯例是在模型测试中使用DB。不管是好是坏,Rails项目都应该这样做

你不必遵循传统,但它会让你的生活更轻松。因此,除非你有令人信服的理由这样做,否则我会避免这样做

为什么要遵循这个惯例?针对DB运行模型测试的惯例很好,原因如下:

熟悉Rails的开发人员可以在遵循约定的情况下更快地了解项目,在这种情况下,他们可以以熟悉的方式调试/编写测试

如果DB在测试中很慢,那么它在生产中可能会很慢,这将通过在开发过程中给您反馈来鼓励良好的数据库设计

更少的代码。将所有从ActiveRecord模型到DB的调用存根将变得很麻烦,这使得在更改对ActiveRecord的调用时,重构需要更多的工作来更新所有的方法存根

升级Rails时,ActiveRecord的接口可能会更改,但存根不会更改。因此,在生产环境中针对DB运行时,您的测试将通过,但可能会失败


可能是重复的,但为什么这里的惯例是好的?为什么它会让事情变得更容易?如果遵循到极端。。。。从长远来看,我会有很多慢一些的测试。还有人愿意插话吗?这些测试真的是集成测试吗?按照@csexton的建议,甚至不升级Rails,但例行的数据库迁移可能会导致代码中断。存根调用可能会错误地让规范通过,因为它们的db视图已经过时。另外,根据定义,ActiveRecord与数据库绑定。因此,我仍然认为它是AccVIECORD环境下的单元测试。在大多数情况下,我们假设AR是有效的。我们不打算编写一个write-AR规范,该规范还运行一个原始SQL查询来检查数据是否确实在数据库中。
allow(coupon1).to receive_message_chain(:coupon_uses, :order) { [coupon_use1, coupon_use2] }