【问题标题】:Testing a method that delegates to another object测试委托给另一个对象的方法
【发布时间】:2017-10-09 12:31:07
【问题描述】:

这是我项目中的模型 -

class Subscription < ActiveRecord::Base
  def active?
    SubscriptionValidationPolicy.new(self).active?
  end
end

当我对active? 进行单元测试时,我应该为活动和非活动状态设置一个subscription 并对其进行断言,还是应该为SubscriptionValidationPolicy 做一个双精度,以某种方式将其注入,然后断言是否@987654325 @被调用了吗?

或者这只是我如何进行测试的固执己见。无论如何我都要测试SubscriptionValidationPolicy,所以为Subscription#active? 方法做一个“基于状态”的测试感觉是多余的。

希望对此有一些想法:)

【问题讨论】:

  • 如果你测试这个策略,我会使用双倍的,但这主要是基于意见的......
  • 我什至不会按原样测试该方法。它是一种单行器,可以进行简单的委托,并且没有任何条件逻辑。再说一次,我还要说你的模型根本不应该有这样的业务逻辑委托。

标签: ruby-on-rails ruby unit-testing rspec


【解决方案1】:

我同意@spickermann 我会按如下方式设置测试:

#spec/models/subscription_spec.rb
#
describe Subscription do 

  let(:subscription) { Subscription.new }
  context '#active? delegation' do 
    let(:policy) {spy('subscription_validation_policy')}
    before :each do 
      allow(SubscriptionValidationPolicy).to receive(:new).and_return(policy)
      subscription.active?
    end

    it 'instantiates a SubscriptionValidationPolicy with self' do 
      expect(SubscriptionValidationPolicy).to have_received(:new).with(subscription)
    end
    it 'calls SubscriptionValidationPolicy#active?' do 
      expect(policy).to have_received(:active?)
    end
  end
end

然后实际测试SubscriptionValidationPolicy#active? 以了解SubscriptionValidationPolicy 规范中的逻辑考虑。

【讨论】:

  • 为了提高可读性;第一个 it 块可以更改为:subscription.active? expect(SubscriptionValidationPolicy).to have_received(:new).with(subscription) 只是因为我喜欢 arrange-act-assert (given-when-then)模式:D
  • @seanriordan08 已更新,因为它确实进行了更简洁的重构,其中调用也可以移动到 before 块
  • 不错。非常感谢各位。很有帮助
猜你喜欢
  • 1970-01-01
  • 2020-06-22
  • 2013-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多