首页 > 解决方案 > 用于 nil:NilClass 的 Rails 控制器 RSpec 未定义方法“编码​​”

问题描述

我有一个带有 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'), type: 'text/csv; charset=UTF-8; header=present',
                                    disposition: 'attachment; filename=admin_logs.csv'
  end

标签: ruby-on-railsrubyrspec

解决方案


我发现我不需要模拟任何这些方法,只需启用 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

推荐阅读