如何与 rspec 中的许多 "it" 个示例共享变量
How to share a variable with many "it" examples in rspec
我正在使用 let 和 factory girl 创建用户记录。但是我想在上下文中的 2 个测试中使用完全相同的变量,因为 user_id 和电子邮件对我发送的外部 API 很重要。
但是我没有运气制作一个变量来跨示例使用。这是我当前的代码
context "User" do
let(:user) { FactoryGirl.create(:user) }
it "should create user and return 'nil'" do
expect(send_preferences(user, "new")).to eq nil
end
it "should not create user preferences again after sending two consecutive same requests" do
expect(send_preferences(user, "new")).to eq "User preferences already saved. No need to re-save them."
end
it "should update user preferences" do
expect(send_preferences(user, "update")).to eq nil
end
end
有什么线索吗?
你可以在 lets 中使用 lets:
context "User" do
let(:email_address) { 'test@test.com' }
let(:user) { FactoryGirl.create(:user, email_address: email_address) }
然后您还可以在所有测试中访问 email_address 变量。
之所以可行,是因为以前每次创建用户时工厂都会随机生成电子邮件地址,因为我们没有在任何地方为其设置值。因此,我们在每次测试中都调用了以下代码:
send_preferences(user, "new")
它调用了 'user' let,它创建了一个具有完全随机电子邮件地址的新用户(因为我们没有给它一个特定的电子邮件值)。因此,在后端 API 调用期间,它每次都发送不同的电子邮件地址。
let(:user) { FactoryGirl.create(:user) }
但是,当我们将电子邮件地址 'let' 定义为 'test@test.com',并按照我提供的代码将其传递到用户工厂时,我们用自己的静态覆盖了随机生成的电子邮件地址值,因此,每次我们再次调用代码时:
send_preferences(user, "new")
它现在触发用户工厂创建,它也采用我们新的 'email_address' let,每次调用时总是设置为 test@test.com 的特定值。
let(:email_address) { 'test@test.com' }
let(:user) { FactoryGirl.create(:user, email_address: email_address) }
因此,当调用后端 API 时,电子邮件地址始终是我们设置的地址。
此外,由于它是一个 let,如果我们愿意,我们可以在任何测试本身中使用该变量。例如:
it 'should set the email address' do
expect(user.email_address).to eq(email_address)
end
很难用几句话来解释,但如果仍然不清楚,请告诉我。
在我看来,anti-pattern 90% 的时间在多个测试之间共享一个实例化变量。
执行以下操作的问题是您将在数据库中创建对象而不进行清理。
before(:all) do
@user = FactoryGirl.create :user
end
当然,您可以执行 before(:after)
块或使用 DatabaseCleaner,但我认为测试尽可能独立是更好的做法。在您的情况下,在对第二次发生的事情做出预期之前先设置 send_preferences
事件:
context "User" do
let(:user) { FactoryGirl.create(:user) }
# ...
it "should not create user preferences again after sending two consecutive same requests" do
send_preferences(user, "new") # Setup
expect(send_preferences(user, "new")).to eq "User preferences already saved. No need to re-save them."
end
it "should update user preferences" do
send_preferences(user, "new") # Setup
expect(send_preferences(user, "update")).to eq nil
end
end
我正在使用 let 和 factory girl 创建用户记录。但是我想在上下文中的 2 个测试中使用完全相同的变量,因为 user_id 和电子邮件对我发送的外部 API 很重要。
但是我没有运气制作一个变量来跨示例使用。这是我当前的代码
context "User" do
let(:user) { FactoryGirl.create(:user) }
it "should create user and return 'nil'" do
expect(send_preferences(user, "new")).to eq nil
end
it "should not create user preferences again after sending two consecutive same requests" do
expect(send_preferences(user, "new")).to eq "User preferences already saved. No need to re-save them."
end
it "should update user preferences" do
expect(send_preferences(user, "update")).to eq nil
end
end
有什么线索吗?
你可以在 lets 中使用 lets:
context "User" do
let(:email_address) { 'test@test.com' }
let(:user) { FactoryGirl.create(:user, email_address: email_address) }
然后您还可以在所有测试中访问 email_address 变量。
之所以可行,是因为以前每次创建用户时工厂都会随机生成电子邮件地址,因为我们没有在任何地方为其设置值。因此,我们在每次测试中都调用了以下代码:
send_preferences(user, "new")
它调用了 'user' let,它创建了一个具有完全随机电子邮件地址的新用户(因为我们没有给它一个特定的电子邮件值)。因此,在后端 API 调用期间,它每次都发送不同的电子邮件地址。
let(:user) { FactoryGirl.create(:user) }
但是,当我们将电子邮件地址 'let' 定义为 'test@test.com',并按照我提供的代码将其传递到用户工厂时,我们用自己的静态覆盖了随机生成的电子邮件地址值,因此,每次我们再次调用代码时:
send_preferences(user, "new")
它现在触发用户工厂创建,它也采用我们新的 'email_address' let,每次调用时总是设置为 test@test.com 的特定值。
let(:email_address) { 'test@test.com' }
let(:user) { FactoryGirl.create(:user, email_address: email_address) }
因此,当调用后端 API 时,电子邮件地址始终是我们设置的地址。
此外,由于它是一个 let,如果我们愿意,我们可以在任何测试本身中使用该变量。例如:
it 'should set the email address' do
expect(user.email_address).to eq(email_address)
end
很难用几句话来解释,但如果仍然不清楚,请告诉我。
在我看来,anti-pattern 90% 的时间在多个测试之间共享一个实例化变量。
执行以下操作的问题是您将在数据库中创建对象而不进行清理。
before(:all) do
@user = FactoryGirl.create :user
end
当然,您可以执行 before(:after)
块或使用 DatabaseCleaner,但我认为测试尽可能独立是更好的做法。在您的情况下,在对第二次发生的事情做出预期之前先设置 send_preferences
事件:
context "User" do
let(:user) { FactoryGirl.create(:user) }
# ...
it "should not create user preferences again after sending two consecutive same requests" do
send_preferences(user, "new") # Setup
expect(send_preferences(user, "new")).to eq "User preferences already saved. No need to re-save them."
end
it "should update user preferences" do
send_preferences(user, "new") # Setup
expect(send_preferences(user, "update")).to eq nil
end
end