【发布时间】:2017-01-02 11:52:47
【问题描述】:
我的测试:
describe TasksCsvsController do
describe '#index' do
let(:params) { {'clients' => {'id' => ['1', '2', '3']}} }
before do
ActiveJob::Base.queue_adapter = :test
end
it 'enqueues tasks csv job' do
get :create, params: params
expect(ProjectsCsvJob).to have_been_enqueued.with(params['clients'])
end
end
end
它测试的控制器:
class TasksCsvsController < ApplicationController
def create
ProjectsCsvJob.perform_now(csv_params.to_unsafe_hash)
redirect_to tasks_path, notice: I18n.t('flashes.tasks_csv_generating', email: current_user.email)
end
private
def csv_params
params.require(:clients).permit(:from, :to, tasks_grid: {}, id: [])
end
end
还有 ActiveJob:
class ProjectsCsvJob < ApplicationJob
queue_as :default
def perform(clients_params)
# it does nothing
end
end
测试没有通过:
Failure/Error: expect(ProjectsCsvJob).to have_been_enqueued.with(params['clients'])
expected to enqueue exactly 1 jobs, with [{"id"=>["1", "2", "3"]}], but enqueued 0
这很奇怪,因为当我在测试期间调试时,params['clients'].to_unsafe_hash 是我所期望的。
但是,当我将控制器的线路更改为
ProjectsCsvJob.perform_later({'id' => ['1', '2', '3']})
测试通过。
【问题讨论】:
-
为什么不使用普通的强参数呢?
params.permit(clients: {})使用空哈希允许任何键。如果参数哈希的结构已知,则应将允许的参数列入白名单。 -
@max 这不是问题所在。我没有将参数列入白名单,因为有很多嵌套哈希。我明确地获取每个值,没有危险。
-
如果您调用
deep_symbolize_keys,哈希值将不匹配,因为{ "a" => 1 } != { a: 1 }。我会按照我的建议或.permit!使用强参数,因为ActionController::Parameters声明了一个==方法,该方法将哈希与字符串或键符号匹配。ActionController::Parameters.new( a: 1 ) == { "a" => 1 } # true -
我再说一遍 - 它与强大的参数无关。我更新了问题以使其清楚 - 使用强参数无济于事。我仍然必须打电话给
to_unsafe_hash,因为ActiveJob不接受ActionController::Parameters。
标签: ruby-on-rails rspec rails-activejob