RSpec:Let 语句有时会出现问题,因为当我执行 get 请求时我需要它们的值存在于数据库中
RSpec: Let statements sometimes an issue as I need their values to exist in the database when I perform a get request
假设我有以下 RSpec 请求测试:
RSpec.describe Api::OrdersController, type: :request do
let(:customer) { FactoryGirl.create(:customer) }
let(:order_1) { FactoryGirl.create(:order, customer: customer) }
let(:order_2) { FactoryGirl.create(:order, customer: customer) }
describe "GET #index" do
it "responds with all the orders of the customer" do
get customer_orders_path(id: customer.id)
expect(json_body.count).to eq(2)
end
end
我在这个测试中遇到的问题是它失败了,这是由于 let 语句的惰性计算导致测试数据库中不存在任何订单。
解决这个问题的一种方法是使用实例变量。然而,问题是我有很多测试都在使用这些 let 语句而没有任何问题,而且对于几个测试来说似乎不合理,其中惰性评估是一个障碍,我必须将我拥有的所有 let 语句重构为实例变量。此外,我有许多 let 语句(大约 20 个),因此将 let 语句和实例变量都保留在 before 语句中并根据情况使用它们的潜在想法将难以管理。
所以我目前看到的唯一解决方案是完全放弃 let 语句。但我希望有更好的选择,因为 let 语句被广泛认为是其可重用性和效率的最佳实践。
有没有我想念的更好的解决方案?有没有办法在执行 get 请求之前触发 let 语句的评估? (尽管这似乎又是一个肮脏的解决方法..)
如果您不想重构任何东西,那么一个选项是使用 let!。
Here is a good explanation for let, let!.
let!(:order_1) { FactoryGirl.create(:order, customer: customer) }
let!(:order_2) { FactoryGirl.create(:order, customer: customer) }
就我个人而言,我会像这样进行测试:
describe Api::OrdersController, type: :controller do
let(:customer) { create(:customer) }
describe "GET #index" do
it "responds with all the orders of the customer" do
create_list(:order, 2, customer: customer)
get customer_orders_path(id: customer.id)
expect(json_body.count).to eq(2)
end
end
end
我通常会尽量避免 let!
因为测试需要不同的东西出现在数据库中,我不想创建超出需要的东西。或者,如果我可以使用存根(build_stubbed
,等等),那将是我的第一选择。
假设我有以下 RSpec 请求测试:
RSpec.describe Api::OrdersController, type: :request do
let(:customer) { FactoryGirl.create(:customer) }
let(:order_1) { FactoryGirl.create(:order, customer: customer) }
let(:order_2) { FactoryGirl.create(:order, customer: customer) }
describe "GET #index" do
it "responds with all the orders of the customer" do
get customer_orders_path(id: customer.id)
expect(json_body.count).to eq(2)
end
end
我在这个测试中遇到的问题是它失败了,这是由于 let 语句的惰性计算导致测试数据库中不存在任何订单。
解决这个问题的一种方法是使用实例变量。然而,问题是我有很多测试都在使用这些 let 语句而没有任何问题,而且对于几个测试来说似乎不合理,其中惰性评估是一个障碍,我必须将我拥有的所有 let 语句重构为实例变量。此外,我有许多 let 语句(大约 20 个),因此将 let 语句和实例变量都保留在 before 语句中并根据情况使用它们的潜在想法将难以管理。
所以我目前看到的唯一解决方案是完全放弃 let 语句。但我希望有更好的选择,因为 let 语句被广泛认为是其可重用性和效率的最佳实践。
有没有我想念的更好的解决方案?有没有办法在执行 get 请求之前触发 let 语句的评估? (尽管这似乎又是一个肮脏的解决方法..)
如果您不想重构任何东西,那么一个选项是使用 let!。
Here is a good explanation for let, let!.
let!(:order_1) { FactoryGirl.create(:order, customer: customer) }
let!(:order_2) { FactoryGirl.create(:order, customer: customer) }
就我个人而言,我会像这样进行测试:
describe Api::OrdersController, type: :controller do
let(:customer) { create(:customer) }
describe "GET #index" do
it "responds with all the orders of the customer" do
create_list(:order, 2, customer: customer)
get customer_orders_path(id: customer.id)
expect(json_body.count).to eq(2)
end
end
end
我通常会尽量避免 let!
因为测试需要不同的东西出现在数据库中,我不想创建超出需要的东西。或者,如果我可以使用存根(build_stubbed
,等等),那将是我的第一选择。