【问题标题】:RSpec message expectations not being met but method is called未满足 RSpec 消息期望,但调用了方法
【发布时间】:2013-01-06 21:28:39
【问题描述】:

我有以下测试:

  describe "Exporter#get_method" do
    before(:each) do
      exporter.should_receive(:get_method).at_least(:once).and_call_original
    end

    it "should get the next terminal value" do
      exporter.send(:get_method).should == :split
    end

    it "should call descend if the current value is a hash" do
      exporter.should_receive(:descend).once

      2.times { exporter.send(:get_method) }
    end

    it "should call ascend if at the end of an array and there is a prologue" do
      exporter.should_receive(:ascend).once

      3.times { exporter.send(:get_method) }
    end
  end

我可以通过调用上升和下降的几个 binding.pry 调用来验证。但是 RSpec 没有看到它。我哪里错了。我想确保被测试的方法确实在正确的情况下调用了其他方法。有没有其他方法可以做到这一点?

【问题讨论】:

    标签: rspec mocking


    【解决方案1】:

    我倾向于从不将期望放在before 块中。在我看来,before 块实际上只是用于设置您正在测试的情况,而不是为了消除期望。当您将exporter.should_receive(:get_method).at_least(:once).and_call_original 移出before 块并将其分布在3 个it 块中时会发生什么情况(在这三种情况下根据需要对其进行编辑)?它可能与其他 should_receive 调用发生冲突。

    另外,如果你打电话给exporter.get_method,而不是exporter.send(:get_method),它会起作用吗?通常,RSpec 旨在测试行为,而不是实现,如果get_method 是私有方法,那么直接测试它没有任何意义。相反,您可能想要做的是为使用该私有方法的方法编写测试。否则,如果不是私有方法,你为什么要使用:send

    【讨论】:

    • 没有骰子。我在特定的 it 块中使用 call_original 遇到了同样的失败。这是一种私有方法。但是,我想通过测试,以便我知道将来是否会破坏它。要么通过改变它做出决定的条件,要么通过修改方法而没有意识到我也修改了行为。
    • 文件中是否还有其他存根(可能在顶部)?这是一个经常让你陷入的陷阱......
    • 不是真的,只有两个 let 语句: let (:exporter) { Export::Exporter.new 'data', [:split, { :to_s => [:split] }] } let ( :formats) { { :xls => Export::Formatters::XLSFormatter, :csv => Export::Formatters::CSVFormatter } }
    • 确保在规范中发送should_receive消息的Export::Exporter的同一个实例是接收ascenddescend的同一个实例。它可能是同一类的不同实例。
    • 将 should_receive 从之前移到测试中应该可以解决这个问题,但它们仍然失败。
    猜你喜欢
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多