我有一个名为justice的表,并创建了该任务来更新kind列:
namespace :populate_jurisdiction do
desc "Populate column kind of jurisdiction model"
task kind: :environment do
Jurisdiction.all.each { |jurisdiction|
case (jurisdiction.kind.nil? || jurisdiction.kind.blank?)
when jurisdiction.name.parameterize == "federal"
jurisdiction.kind = 1
when jurisdiction.name.parameterize == "estadual"
jurisdiction.kind = 2
when jurisdiction.name.parameterize == "municipal"
jurisdiction.kind = 3
when jurisdiction.name.parameterize == "privado"
jurisdiction.kind = 4
end
jurisdiction.save!
}
end
end
然后创建test
require "spec_helper"
Rails.application.load_tasks
describe "populate_jurisdiction:kind" do
context "when update kind column of jurisdiction" do
let(:federal) { create(:jurisdiction, name: "Federal", kind: nil) }
let(:state) { create(:jurisdiction, name: "Estadual", kind: nil) }
let(:municipal) { create(:jurisdiction, name: "Municipal", kind: '') }
let(:particular) { create(:jurisdiction, name: "Privado", kind: '') }
it "when kind column is updated" do
Rake::Task["populate_jurisdiction:kind"].invoke
expect(federal.kind).to eq(1)
expect(state.kind).to eq(2)
expect(municipal.kind).to eq(3)
expect(particular.kind).to eq(4)
end
end
end
当我在rails控制台中运行任务时,它可以工作,但是当我运行测试时,我得到了这个错误
Failures:
1) populate_jurisdiction:kind when update kind column of jurisdiction when kind column is updated
Failure/Error: expect(federal.kind).to eq(1)
expected: 1
got: nil
(compared using ==)
我做错了什么?我该如何修复这个测试?
在任何司法管辖区创建之前调用rake任务。当你说:
let(:federal) { create(:jurisdiction, name: "Federal", kind: nil) }
将在您第一次在测试中访问federal
时创建它,然后在测试的持续时间内记住它。所以在rake任务运行之前没有federal
。如果您使用let!
而不是let
,并在任务运行后重新加载权限,您将获得更好的结果。
顺便说一句,你的rake任务并不像你想象的那样工作。case
有两种形式:
case expr
when value1
...
when value2
...
end
和
case
when expr1
...
when expr2
...
end
当你打算使用第二种形式时,你使用了第一种形式,并且你的代码意外地工作了。我怀疑当你运行这个时,所有的kind
s都是nil
,否则你最终会做:
case false
...
end
,您将进入jurisdiction.name.parameterize
测试失败的第一个分支。
你的任务应该看起来更像:
Jurisdiction.all.reject { |j| j.kind.blank? }.each do |jurisdiction|
case jurisdiction.name.parameterize
when 'federal'
jurisdiction.kind = 1
when 'estadual'
jurisdiction.kind = 2
when 'municipal'
jurisdiction.kind = 3
when 'privado'
jurisdiction.kind = 4
end
jurisdiction.save!
end
或:
Jurisdiction.all.reject { |j| j.kind.blank? }.each do |jurisdiction|
jurisdiction.kind = case jurisdiction.name.parameterize
when 'federal' then 1
when 'estadual' then 2
when 'municipal' then 3
when 'privado' then 4
end
jurisdiction.save!
end
如果kind
是一个整数,那么kind.blank?
只有在kind.nil?
的时候才会为真,这样就可以被推入数据库了:
Jurisdiction.where(kind: nil).each do |jurisdiction|
jurisdiction.kind = case jurisdiction.name.parameterize
when 'federal' then 1
when 'estadual' then 2
when 'municipal' then 3
when 'privado' then 4
end
jurisdiction.save!
end
看起来#parameterize
在这种情况下只会将name
转换为小写所以将所有逻辑推入数据库:
# This is an SQL CASE expression, not a Ruby one
Jurisdiction.where(kind: nil).update_all(%q(
kind = case lower(name)
when 'federal' then 1
when 'estadual' then 2
when 'municipal' then 3
when 'privado' then 4
end
))
当您调用rake任务时,没有管辖权,这就是您得到nil
的原因。例如,federal管辖权仅在调用federal.kind
时的rake任务之后创建。
require "spec_helper"
Rails.application.load_tasks
describe "populate_jurisdiction:kind" do
context "when update kind column of jurisdiction" do
let(:federal) { create(:jurisdiction, name: "Federal", kind: nil) }
let(:state) { create(:jurisdiction, name: "Estadual", kind: nil) }
let(:municipal) { create(:jurisdiction, name: "Municipal", kind: '') }
let(:particular) { create(:jurisdiction, name: "Privado", kind: '') }
it "when kind column is updated" do
# NOTE: jurisdictions are not created until `let` blocks are called.
federal
state
municipal
particular
Rake::Task["populate_jurisdiction:kind"].invoke
# NOTE: `let` return values are memoized, second call will just
# retrieve the value. You have to reload the models as well
# to get the updated values from the database.
expect(federal.reload.kind).to eq(1)
expect(state.reload.kind).to eq(2)
expect(municipal.reload.kind).to eq(3)
expect(particular.reload.kind).to eq(4)
end
end
end
https://relishapp.com/rspec/rspec-core/v/3-11/docs/helper-methods/let-and-let