【问题标题】:how do you mock dependent methods using rspec你如何使用 rspec 模拟依赖方法
【发布时间】:2014-06-24 21:57:44
【问题描述】:

我正在尝试为我的黄瓜结果编写一个自定义解析器。为此,我想围绕它编写 rspec 测试。我目前拥有的如下:

describe 'determine_test_results' do
  it 'returns a scenario name as the key of the scenario results, with the scenario_line attached' do
    pcr = ParseCucumberJsonReport.new
    expected_results = {"I can login successfully"=>{"status"=>"passed", "scenario_line"=>4}}
    cucumber_results = JSON.parse(IO.read('example_json_reports/json_passing.json'))
    pcr.determine_test_results(cucumber_results[0]).should == expected_results
  end
end

问题是,determine_test_results 有一个名为determine_step_results 的子方法,这意味着这实际上是两个方法之间的集成测试,而不是determine_test_results 的单元测试。

我将如何模拟来自确定步骤结果的“响应”?

假设 determine_step_results 返回 {"status"=>"passed", "scenario_line"=>4}

我尝试过的:

pcr.stub(:determine_step_results).and_return({"status"=>"passed", "scenario_line"=>6})

allow(pcr).to receive(:determine_step_results).and_return({"status"=>"passed", "scenario_line"=>6})

【问题讨论】:

    标签: ruby rspec mocking rspec2


    【解决方案1】:

    您可以利用存根来完成您想要完成的任务。 Project: RSpec Mocks 2.3 将是关于这个特殊案例的好读物。我在下面添加了一些代码作为建议。

    describe 'determine_test_results' do
     it 'returns a scenario name as the key of the scenario results, with the scenario_line       attached' do
       pcr = ParseCucumberJsonReport.new
       expected_results = {"I can login successfully"=>{"status"=>"passed", "scenario_line"=>4}}
    
       # calls on pcr will return expected results every time determine_step_results is called in any method on your pcr object.
       pcr.stub!(:determine_step_results).and_return(expected_results)
    
       cucumber_results = JSON.parse(IO.read('example_json_reports/json_passing.json'))
       pcr.determine_test_results(cucumber_results[0]).should == expected_results
     end
    end
    

    【讨论】:

    • 更好地使用新的expect API - allow(pcr).to receive(:determine_step_results).and_return(expected_results) github.com/rspec/rspec-mocks#method-stubs
    • 这些都不起作用,我将scenario_line号更改为6并期望“预期{“我可以成功登录”=>{“status”=>“passed”,“scenario_line”=> 4}} got {"我可以登录成功"=>{"status"=>"passed", "scenario_line"=>6}}
    • @UriAgassi 看我之前的评论
    • @MattWestlake 你不是要写allow(pcr).to receive(:determine_step_results).and_return({"status"=>"passed", "scenario_line"=>4})吗?
    • @UriAgassi 我写了“scenario_line”=>6 以确保模拟覆盖了实际功能。如果是这样,我会预料到无法显示“预期的“scenario_line”=>4 得到了“scenario_line”=>6”,但事实并非如此。
    【解决方案2】:

    如果determine_test_results 所做的只是调用determine_step_results,你不应该真正测试它,因为它是微不足道的......

    如果你决定测试它,你只需要测试它是否调用了委托函数,并返回 whatever 传递给它:

    describe ParseCucumberJsonReport do
      describe '#determine_test_results' do
        it 'calls determine_step_results' do
          result = double(:result)
          input = double(:input)
          expect(subject).to receive(:determine_step_results).with(input).and_return(result)
    
          subject.determine_test_results(input).should == result
        end
      end
    end
    

    如果它正在做更多事情(例如将结果添加到更大的哈希中),您也可以描述它:

    describe ParseCucumberJsonReport do
      describe '#determine_test_results' do
        it 'calls determine_step_results' do
          result = double(:result)
          input = double(:input)
          expect(subject).to receive(:determine_step_results).with(input).and_return(result)
          expect(subject.larger_hash).to receive(:merge).with(result)
    
          subject.determine_test_results(input).should == result
        end
      end
    end
    

    【讨论】:

    • determine_step_results 不是唯一发生的事情,它还将结果放入更大的哈希中。此外,很难理解您的示例中发生了什么,因为“主题”没有定义,输入或结果也没有。
    猜你喜欢
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    • 2023-03-05
    • 2013-09-11
    相关资源
    最近更新 更多