测试 controller_spec 中对象的实例化,然后对生成的对象调用方法失败

Testing instantiation of an object in a controller_spec, then calling a method on the resulting object fails

我有一个看起来像这样的控制器规格

describe ExportController do
  describe 'GET index' do
    target_params = {type:'a', filter: 'b'}
    expect(DataFetcher).to receive(:new).with(target_params)
    get :index
  end
end

控制器看起来像这样

class ExportController < ApplicationController
  def index
    @fetcher = DataFetched.new(target_params)

    ...
  end
end

如果我 运行 这样的规格,一切都很酷。然而,我想对生成的 DataFetcher 对象做一些事情

class ExportController < ApplicationController
  def index
    @fetcher = DataFetcher.new(target_params)
    @list = @fetcher.fetch_list
    ...
  end
end

现在,当我 运行 规范时,它因无方法错误而失败

NoMethodError
  undefined method 'fetch_list' for nil:NilClass

这是怎么回事?问题是,当我通过我的实际应用程序点击这个控制器时,它会按预期工作。 rspec 在幕后做什么,我该如何正确设置它?

谢谢大家

您的 expect 语句导致 nilnew 中被 return 编辑,new 没有定义 fetch_list。如果您希望该行成功,您需要 return 实现 fetch_list 方法的东西,如下所示:

expect(DataFetcher).to receive(:new).with(target_params)
  .and_return(instance_double(DataFetcher, fetch_list: [])

或者您可以在末尾添加:.and_call_original 哪个更干净

expect(DataFetcher).to receive(:new).with(target_params)
  .and_call_original