问题描述
我有一个带有ActiveAdmin面板的Rails 6应用程序,该面板具有一种使用管理员活动日志创建CSV文件的方法。我想为该操作创建RSpec测试,如下所示:
admin/users_spec.rb
describe Admin::UsersController,type: :controller do
include Devise::Test::ControllerHelpers
before { sign_in admin }
let!(:admin) { create(:admin_user) }
describe '#import_csv' do
let(:csv_admin_log_generator_instance) { instance_double(::AdminLogData::CsvAdminLogGenerator) }
before do
allow(::AdminLogData::CsvAdminLogGenerator).to receive(:new).and_return(csv_admin_log_generator_instance)
allow(csv_admin_log_generator_instance).to receive(:call)
get :index
end
it 'accepts send_data' do
get :import_csv
expect(csv_admin_log_generator_instance).to receive(send_data)
end
end
end
但这给我一个错误:
1) Admin::UsersController#import_csv accepts send_data
Failure/Error:
send_data file.encode('UTF-8'),type: 'text/csv; charset=UTF-8; header=present',disposition: 'attachment; filename=admin_logs.csv'
NoMethodError:
undefined method `encode' for nil:NilClass
这是我要测试的方法(其行为类似于控制器)。
collection_action :import_csv,method: :get do
file = ::AdminLogData::CsvAdminLogGenerator.new.call
send_data file.encode('UTF-8'),disposition: 'attachment; filename=admin_logs.csv'
end
解决方法
我相信问题出在allow(csv_admin_log_generator_instance).to receive(:call)
,您对此方法进行了存根,其结果为nil。您需要强制它调用原始方法allow(csv_admin_log_generator_instance).to receive(:call).and_call_original
我发现我不需要模拟任何这些方法,而只是简单地启用paper_trail gem并按如下所示更新规范。
describe Admin::UsersController,type: :controller do
include Devise::Test::ControllerHelpers
let!(:admin) { create(:admin_user) }
before do
sign_in admin
get :index
end
it_behaves_like 'controller response status',200
describe '#import_csv' do
it_behaves_like 'controller response status',200
it 'create CSV file',versioning: true do
admin.update!(email: 'steven.hyde@example.com')
get :import_csv
expect(response.header['Content-Type']).to include 'text/csv'
end
end
end