ruby 工厂机器人和在RSpec中登录的问题

afdcj2ne  于 2023-02-03  发布在  Ruby
关注(0)|答案(1)|浏览(105)

我在使用Factory bot和以指定用户身份登录时遇到了问题。我尝试在rspec中运行一个简单的Edit测试。

require "rails_helper"

RSpec.describe "Treat management", :type => :system do
  before do
    treat =    FactoryBot.create(:treat)
    user = build(:user, email: 'wojtek@gmail.com', password: 'password')
    login_as(user)
    driven_by(:selenium_chrome_headless)
  end
  it "enables me to edit treats" do
    visit root_path
    click_button 'Edit'
    fill_in 'Name', with: 'A new name'
    fill_in 'Content', with: 'A new content'
    click_button "Update Treat"

    expect(page).to have_text("Treat was edited successfully")
  end
end

这是我的Treat工厂。Treat有名称、内容、发送方和接收方外键

FactoryBot.define do
  factory :treat do
     name {'my first factory treat'}
     content {'this is my first treat created by a factory'}
      giver factory: :user
     receiver factory: :user
  end
end

当然还有用户工厂。用户是通过电子邮件和密码定义的

FactoryBot.define do
  factory :user do
     email {Faker::Internet.email}
     password {'password'}
  end
end

而且你必须知道编辑按钮只有在登录用户同时也是给予者的时候才会出现。我已经询问过了,我的Treat工厂应该配置得很好。请帮助我解决这个问题。如果需要任何其他代码部分,请在注解中告诉我,我会相应地更新。当然,我知道有一种更简单的方法来编写这个测试,但是工厂的使用是一个要求。
1
我试过在工厂中对用户进行硬编码(没有Faker gem),但这会触发验证错误-电子邮件已被采取。

k4ymrczo

k4ymrczo1#

现在,FactoryBot.create(:treat)将根据工厂定义为giver创建一个User,为receiver创建一个User

FactoryBot.define do
  factory :treat do
     name {'my first factory treat'}
     content {'this is my first treat created by a factory'}
     giver factory: :user # tells the factory to create a User from the User Factory
     receiver factory: :user # tells the factory to create a User from the User Factory
  end
end

您将在测试中调用它,但随后创建第三个用户进行测试

before do
    treat = FactoryBot.create(:treat) # 2 users created 
    # changed to `create` since as @max pointed out `build` does not actually create a `User` 
    user = create(:user, email: 'wojtek@gmail.com', password: 'password') # third user
  end

这第三个用户既不是giver也不是Treatreceiver,这就是您的测试失败的原因。
相反,您可以通过传递参数来覆盖Factory中的定义。在这种情况下,您希望测试中的User对象是Treatgiver,因此我们可以如下所示实现这一点(我使用了@max测试方案的修改版本,因为这是设置此方案的首选方法)

require "rails_helper"
RSpec.describe "Treat management", type: :system do

  let(:user) { create(:user) }
 
  before do 
    driven_by(:selenium_chrome_headless)
  end

  context 'A Treat#giver' do 
    let!(:treat) {create(:treat, giver: user)}

    before do 
      login_as(user)
    end

    it "can edit Treats they've given" do
      visit root_path
      click_button 'Edit'
      fill_in 'Name', with: 'A new name'
      fill_in 'Content', with: 'A new content'
      click_button "Update Treat"
      expect(page).to have_text("Treat was edited successfully")
    end
  end 
end

这里我们将默认创建的“giver”用户替换为let块中定义的user方法返回的特定用户,这样可以确保user == treat.giver,从而使您的测试能够成功。

相关问题