【问题标题】:RSpec test if method is being called inside a methodRSpec 测试方法是否在方法内部被调用
【发布时间】:2021-04-23 14:07:05
【问题描述】:

所以,我想用 RSpec 模拟测试以下代码行。

class BaseService
  MAX_BODY_SIZE = 100000.freeze

  def translate(body, language, account)
    return body if body.blank?

    translate_body_in_chunks(body, language, account) if body.size > MAX_BODY_SIZE
  end

  def translate_body_in_chunks(body, language, account)
    # some API call that I don't want to call while testing
  end
end

我想测试translate_body_in_chunks是否被调用。

到目前为止的 RSpec 实现

body = 'a' * 10000000
mock = double(described_class)
allow(mock).to receive(:translate).with(body, 'en', '')

expect(mock).to receive(:translate_body_in_chunks)

我知道这个测试行不通。我只是在此处添加它以提示您要测试的内容。

【问题讨论】:

  • 您可以在实际的服务对象上期待消息,而不是模拟对象。
  • 我该怎么做?你能帮我吗?我是 RSpec 的新手。
  • 和你在这里做的差不多,但是使用真实的对象:service = BaseService.new; expect(service).to receive(:translate_body_in_chunks); service.translate(body, "en", "")

标签: ruby-on-rails ruby rspec


【解决方案1】:

这样的事情应该可以工作:

describe BaseService do
  describe '#translate' do
    context 'with a body exceeding MAX_BODY_SIZE' do
      let(:body) { 'a' * (BaseService::MAX_BODY_SIZE + 1) }

      it 'calls translate_body_in_chunks' do
        expect(subject).to receive(:translate_body_in_chunks)

        subject.translate(body, 'en', '')
      end
    end
  end
end

subject 指的是通过BaseService.new 创建的实例。

请注意,一般情况下,您不应测试方法的实现细节。相反,请尝试测试该方法的行为

【讨论】:

  • 这应该可以实现既定目标,但有些人会说您不应该测试被测对象的私有内部。相反,验证传出消息(如 API 调用)。
猜你喜欢
  • 1970-01-01
  • 2014-02-11
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
  • 2021-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多