首页 > 解决方案 > 如何为 RSpec 中的块生成对象的方法编写单元测试

问题描述

我有一个类,它实现了一个.call产生块对象的方法,我想学习如何为此编写单元测试。这就是我所拥有的。

module A
  class B < Service
    def call(object_id:)
      @object = Something.find(object_id)
      @object.update(status: 'done')
      yield @object
    end

    def set_to_in_progress
      @object.update(status: 'in_progress')
    end
  end
end

class Service
  def self.call(*args); new.call(*args); end
end

然后我像这样使用它:

A::B.call(obj) do |object|
  object.set_to_in_progress if some_other_condition?
end

我需要能够为call测试状态是否已更改为已完成或正在进行的方法编写单元测试。这是我所拥有的:

RSpec.describe A::B, :unit do
  let(:object) { create(:something, id: 1, status: 'in_progress') }

  it 'updates the status to done' do
    described_class.call(object.id) do |???|
      ???
    end

    expect(object.status).to equal('done')
  end

  it 'updates the status to in progress' do
    described_class.call(object.id) do |???|
      ???
    end

    expect(object.status).to equal('in_progress')
  end
end

标签: rubyrspecrspec-railsrspec3

解决方案


您可以在以下位置返回对象#call

def call(object_id:)
  @object = Something.find(object_id)
  @object.update(status: 'done')
  yield @object
  @object
end    

然后在测试中你可以这样做:

object = described_class.call(object.id)
expect(object.status).to eq('in_progress')

推荐阅读