如何修复 RSpec 中的任务测试?
How to fix a task test in RSpec?
我有一个名为 Jurisdiction 的 table 并创建了该任务来更新类型列:
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
然后我创建了那个测试
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 任务时,没有管辖权,这就是您得到 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
您正在在创建任何司法管辖区之前调用抽成任务。当你这样说时:
let(:federal) { create(:jurisdiction, name: "Federal", kind: nil) }
当您在测试中首次访问它时将创建 federal
,然后在测试期间记住它。所以没有 federal
直到你的 rake 任务 运行s 之后。如果您使用 let!
而不是 let
并在任务 运行 之后重新加载管辖区,您会得到更好的结果。
顺便说一句,您的佣金任务并不像您认为的那样有效。 case
有两种形式:
case expr
when value1
...
when value2
...
end
和
case
when expr1
...
when expr2
...
end
当您打算使用第二种形式时,您使用的是第一种形式,而您的代码却意外地起作用了。我怀疑当你 运行 时你所有的 kind
都是 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
))
我有一个名为 Jurisdiction 的 table 并创建了该任务来更新类型列:
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
然后我创建了那个测试
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 任务时,没有管辖权,这就是您得到 nil
的原因。例如,federal 管辖权仅在您调用 federal.kind
.
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
您正在在创建任何司法管辖区之前调用抽成任务。当你这样说时:
let(:federal) { create(:jurisdiction, name: "Federal", kind: nil) }
当您在测试中首次访问它时将创建 federal
,然后在测试期间记住它。所以没有 federal
直到你的 rake 任务 运行s 之后。如果您使用 let!
而不是 let
并在任务 运行 之后重新加载管辖区,您会得到更好的结果。
顺便说一句,您的佣金任务并不像您认为的那样有效。 case
有两种形式:
case expr
when value1
...
when value2
...
end
和
case
when expr1
...
when expr2
...
end
当您打算使用第二种形式时,您使用的是第一种形式,而您的代码却意外地起作用了。我怀疑当你 运行 时你所有的 kind
都是 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
))