我有一个奇怪的问题。我为一个用户/交易has_many / has_many关系创建了一个工厂user_deals,但是看起来rspec迫使我现在断言用户即使我不需要一个用户(事实上用户只记录了我的数据库并且在应用程序中需要网络访问者登录)
此测试不起作用:
context "As NON SIGNED-IN visitor" do
describe "HP card has the right content and behavior on small screens (1-column view)", :js => true do
let(:subject) { ApplicationController.new }
let(:deal_for_german_people) { create(:deal_skips_validate,
:country => "Germany",
:title => "title of deal for German people") }
let(:deal_for_german_people2) { create(:deal_skips_validate,
:country => "Germany",
:title => "title 2 of deal for German people") }
before do
resize_window_to_mobile
end
after do
resize_window_default
end
it "plus and minus icons behave correctly" do
visit root_path
# user sees on mobile the little "plus" icon by default
expect(page).to have_css('.card-detail-opener', visible: true)
end
end
但如果我添加create(:user)并创建“user_deals”,则测试通过。但我在上下文中“未登录用户”,那么我为什么要创建一个user和user_deals?
context "As NON SIGNED-IN visitor" do
describe "HP card has the right content and behavior on small screens (1-column view)", :js => true do
let(:subject) { ApplicationController.new }
let(:user) { create(:user,
user_country_name: 'Germany') }
let(:deal_for_german_people) { create(:deal_skips_validate,
:country => "Germany",
:title => "title of deal for German people") }
let(:deal_for_german_people2) { create(:deal_skips_validate,
:country => "Germany",
:title => "title 2 of deal for German people") }
before do
resize_window_to_mobile
create(:user_deal, user: user, deal: deal_for_german_people)
create(:user_deal, user: user, deal: deal_for_german_people2)
end
after do
resize_window_default
end
it "plus and minus icons behave correctly" do
visit root_path
# user sees on mobile the little "plus" icon by default
expect(page).to have_css('.card-detail-opener', visible: true)
end
end
另外,还在调查这种奇怪的原因,我发现如果我在测试开始时不使用“let:”,而是在...之前创建变量@deals ...它可以在不创建用户的情况下工作(但是我想使用rspec“let”来干燥并应用rspec best practices)
describe "HP card has the right content and behavior on small screens (1-column view)", :js => true do
let(:subject) { ApplicationController.new }
before do
resize_window_to_mobile
@deal_for_german_people = FactoryGirl.build( :deal,
:country => "Germany",
:title => "title of deal for German people").save(validate: false)
@deal_for_german_people2 = FactoryGirl.build( :deal,
:country => "Germany",
:title => "title 2 of deal for German people").save(validate: false)
end
after do
resize_window_default
end
it "plus and minus icons behave correctly" do
visit root_path
expect(page).to have_css('.card-detail-opener', visible: true)
end
模型
class Deal < ActiveRecord::Base
has_many :user_deals, dependent: :destroy
has_many :users, through: :user_deals
end
class User < ActiveRecord::Base
has_many :user_deals
has_many :deals, through: :user_deals
end
class UserDeal < ActiveRecord::Base
belongs_to :user, :foreign_key => 'user_id'
belongs_to :deal, :foreign_key => 'deal_id'
end
表user_deals的结构
# Table name: user_deals
#
# id :integer not null, primary key
# user_id :integer
# deal_id :integer
# number_of_clicks :integer default(0)
# created_at :datetime
# updated_at :datetime
工厂用户
FactoryGirl.define do
factory :user do
sequence(:email) { |n| "person#{n}@example.com" }
password "vddfdf"
password_confirmation "vddfdf"
confirmed_at Time.now
confirmation_token nil
trait :superadmin do
role :superadmin
end
trait :with_deals do
after(:create) do |user|
create_list(:deal, 5, user: user)
end
end
end
end
工厂user_deal
FactoryGirl.define do
factory :user_deal do
association :user
association :deal
trait :few_clicks do
number_of_clicks 1
end
trait :many_clicks do
number_of_clicks 4
end
end
end
答案 0 :(得分:1)
我的猜测是你期待两个
let(:deal_for_german_people) ...
let(:deal_for_german_people2) ...
在it
块之前创建。但是,在您的第一个失败的情况下,情况并非如此,因为您没有在it
块的任何部分调用/使用这些变量。您应该将let
变量视为等待运行的代码。
我认为您想要的是let!
,它会立即运行。
以下可能会起作用
context "As NON SIGNED-IN visitor" do
describe "HP card has the right content and behavior on small screens (1-column view)", :js => true do
...
let!(:deal_for_german_people) { create(:deal_skips_validate,
:country => "Germany",
:title => "title of deal for German people") }
let!(:deal_for_german_people2) { create(:deal_skips_validate,
:country => "Germany",
:title => "title 2 of deal for German people") }
...
end
end