【问题标题】:Stubbing a method correctly in rspec在 rspec 中正确存根方法
【发布时间】:2020-07-29 20:08:56
【问题描述】:

我在尝试存根方法时遇到了麻烦。我有以下工作:

动物关系工作

def perform(user_id, animal_id)
  user = User.find(User_id)
  animal_data = Animal::Zoo.internal_data(animal_id)
  owner_score = OwnerService.new.generate_score!(animal_data, user)

  AnimalMailer.animal_tips_message(user, owner_score).deliver_later
end

我想同时存根 internal_data 方法和 OwnerService.generate_score 并测试作业是否能够使用正确的参数调用 AnimalMailer.animal_tips_message

let(:m) { AnimalRelationJob.new.perform(user_id, animal_id) }

before { 
  allow(OwnerAuth::Validation).to receive(:create_key) { true }
  allow_any_instance_of(OwnerService.new).to receive(:generate_score).and_return(100)
  allow(Animal::Zoo).to receive(:internal_data).and_return(1)

}

it "should call the mailer" do
  expect(m).to receive(animal_tips_message).with(admin_user, 100)
end

我现在收到错误:

undefined method `ancestors' for #<OwnerService:0x0029812>

我认为它可能来自我从 OwnerService 初始化中存根的方法

class OwnerService

  def initialize
    validated = OwnerAuth::Validation.create_key(....)
  end

【问题讨论】:

    标签: ruby-on-rails rspec stub


    【解决方案1】:

    但是上面一直在调用 OwnerService 类。我做错了什么?

    你在一个临时对象上存根方法,你从OwnerService.new得到的那个。然后perform 创建另一个临时对象(自然没有任何存根)并调用该方法。

    解决这个问题的几种方法:

    1. 劫持对象创建

      fake = double
      allow(OtherService).to receive(:new).and_return(fake)
      allow(fake).to receive(:generate_score).and_return(100)
      
    2. 存根所有实例

       allow_any_instance_of(OtherService).to receive(:generate_score).and_return(100)
      
    3. 重新组织代码,使其更易于测试(dependency injection 等)

    【讨论】:

      猜你喜欢
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 2014-09-23
      • 2013-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-03-03
      • 1970-01-01
      相关资源
      最近更新 更多