【问题标题】:RSpec - trying to stub a method that returns its own argumentRSpec - 试图存根返回自己的参数的方法
【发布时间】:2016-05-07 20:34:39
【问题描述】:

我有一个方法,我试图在我的单元测试中存根。使用一个参数(字符串)调用真正的方法,然后发送一条文本消息。我需要将方法存根,但返回作为参数传入的字符串。

我在 RSpec 测试中的代码是这样的:

allow(taxi_driver).to receive(:send_text).with(:string).and_return(string)

这会返回:

NameError: undefined local variable or method 'string'

如果我将返回参数更改为:string,我会收到以下错误:

Please stub a default value first if message might be received with other args as well

我已经尝试使用谷歌搜索并查看 relishapp.com 网站,但无法找到看似简单明了的问题的答案。

【问题讨论】:

  • send_text 是如何被调用的?错误的原因正是它所说的:你没有在任何地方定义string。你给with 的参数应该是你期望方法接收的实际值(我怀疑是符号:string),你给and_return 的参数应该是你想要存根返回的实际值,例如allow(taxi_driver).to receive(:send_text).with("I'm the input text").and_return("I'm the output text").
  • 我的方法被这样调用:send_text("the time now is #{Time.now}")。字符串根据时间而变化,这就是为什么我需要模拟来返回变化的字符串。也许它不在模拟的范围内这样做?
  • 实际上,我只是按照您编辑中的建议进行了操作,现在我设法让它工作了。只是它看起来真的很难看(我使用的字符串比我的示例长得多),我会考虑将它们分配给一个变量,现在编码了几个小时后真的很累。谢谢。

标签: ruby rspec stubbing


【解决方案1】:

你可以传递一个块:

allow(taxi_driver).to receive(:send_text).with(kind_of(String)){|string| string }
expect(taxi_driver.send_text("123")).to eq("123")

【讨论】:

    【解决方案2】:

    我的方法是这样调用的:send_text("现在的时间是#{Time.now}")。字符串根据时间而变化,这就是为什么我需要模拟来返回变化的字符串。也许它不在模拟的范围内这样做?

    在这种情况下,我通常使用Timecop gem 来冻结系统时间。这是一个示例用例:

    describe "#send_text" do
      let(:taxi_driver) { TaxiDriver.new }
    
      before do
        Timecop.freeze(Time.local(2016, 1, 30, 12, 0, 0))
      end
    
      after do
        Timecop.return
      end
    
      example do
        expect(taxi_driver.send_text("the time now is #{Time.now}")).to eq \
          "the time now is 2016-01-30 12:00:00 +0900"
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2018-08-19
      • 2016-03-03
      • 2021-03-15
      • 2010-12-15
      • 2013-01-31
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多