测试 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
语句导致 nil
从 new
中被 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
我有一个看起来像这样的控制器规格
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
语句导致 nil
从 new
中被 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