如何使用 rspec 和 factorygirl 测试 invalid_attribute
How to test invalid_attribute using rspec and factorygirl
我正在学习如何在 rails 上进行测试 tutorial。
教程的一部分显示了如何编写 invalid_attribute
测试:
require 'rails_helper'
RSpec.describe ContactsController, type: :controller do
describe "POST #create" do
context "with valid attributes" do
it "create new contact" do
post :create, contact: attributes_for(:contact)
expect(Contact.count).to eq(1)
end
end
context "with invalid attributes" do
it "does not create new contact" do
post :create, contact: attributes_for(:invalid_contact)
expect(Contact.count).to eq(0)
end
end
end
end
我不明白 :contact
和 :invalid_contact
指向哪里。
:contact
是否指向Contact
class?好像是FactoryGirl's gh.如果是这样,那我怎么创建:invalid_contact
因为没有:invalid_contact
class?
我已经尝试了post :create, contact: attributes_for(:contact, :full_name => nil)
,但还是失败了。
spec/factories/contacts.rb
:
FactoryGirl.define do
factory :contact do
full_name { Faker::Name.name }
email { Faker::Internet.email }
phone_number { Faker::PhoneNumber.phone_number }
address { Faker::Address.street_address }
end
end
第一次测试,with valid attributes
通过。在模型上,有存在验证 validates_presence_of :full_name, :email, :phone_number, :address
。我要添加什么才能通过 "with invalid attributes"
测试?
工厂将使用同名的class。所以你的 :contact
工厂将使用 Contact
class。您可以通过指定要使用的 class 来为无效联系人创建新工厂。
factory :invalid_contact, class: Contact do
full_name nil
end
也可以使用特征来避免拥有两个不同的工厂。
FactoryGirl.define do
factory :contact do
full_name { Faker::Name.name }
email { Faker::Internet.email }
phone_number { Faker::PhoneNumber.phone_number }
address { Faker::Address.street_address }
trait :invalid do
full_name nil
end
end
end
然后与attributes_for(:contact, :invalid)
一起使用
您 link 的教程说:
Following the spec above, write a spec that uses invalid attributes to
create a new contact. This spec should check that the contact is not
created.
因此您需要弄清楚如何使用 :contact
的示例来测试 :invalid_contact
。
您只需在规范中添加 let
:
Use let to define a memoized helper method. The value will be cached
across multiple calls in the same example but not across examples.
Source: https://www.relishapp.com/rspec/rspec-core/v/3-5/docs/helper-methods/let-and-let
那么您的控制器规格将如下所示:
...
let(:invalid_contact) { create(:contact, name: nil) }
context "with invalid attributes" do
it "does not create new contact" do
post :create, contact: attributes_for(invalid_contact)
expect(Contact.count).to eq(0)
end
end
...
这样 #post
动作 params
是从 invalid_contact
中提取的
或者正如@fanta 在评论中建议的那样,您可以向您的工厂添加一个 trait
。我更喜欢我的方法,因为其他人看你的代码就会知道为什么 invalid_contact
应该无效而不看 :contacts
工厂
我正在学习如何在 rails 上进行测试 tutorial。
教程的一部分显示了如何编写 invalid_attribute
测试:
require 'rails_helper'
RSpec.describe ContactsController, type: :controller do
describe "POST #create" do
context "with valid attributes" do
it "create new contact" do
post :create, contact: attributes_for(:contact)
expect(Contact.count).to eq(1)
end
end
context "with invalid attributes" do
it "does not create new contact" do
post :create, contact: attributes_for(:invalid_contact)
expect(Contact.count).to eq(0)
end
end
end
end
我不明白 :contact
和 :invalid_contact
指向哪里。
:contact
是否指向Contact
class?好像是FactoryGirl's gh.如果是这样,那我怎么创建:invalid_contact
因为没有:invalid_contact
class?
我已经尝试了post :create, contact: attributes_for(:contact, :full_name => nil)
,但还是失败了。
spec/factories/contacts.rb
:
FactoryGirl.define do
factory :contact do
full_name { Faker::Name.name }
email { Faker::Internet.email }
phone_number { Faker::PhoneNumber.phone_number }
address { Faker::Address.street_address }
end
end
第一次测试,with valid attributes
通过。在模型上,有存在验证 validates_presence_of :full_name, :email, :phone_number, :address
。我要添加什么才能通过 "with invalid attributes"
测试?
工厂将使用同名的class。所以你的 :contact
工厂将使用 Contact
class。您可以通过指定要使用的 class 来为无效联系人创建新工厂。
factory :invalid_contact, class: Contact do
full_name nil
end
也可以使用特征来避免拥有两个不同的工厂。
FactoryGirl.define do
factory :contact do
full_name { Faker::Name.name }
email { Faker::Internet.email }
phone_number { Faker::PhoneNumber.phone_number }
address { Faker::Address.street_address }
trait :invalid do
full_name nil
end
end
end
然后与attributes_for(:contact, :invalid)
您 link 的教程说:
Following the spec above, write a spec that uses invalid attributes to create a new contact. This spec should check that the contact is not created.
因此您需要弄清楚如何使用 :contact
的示例来测试 :invalid_contact
。
您只需在规范中添加 let
:
Use let to define a memoized helper method. The value will be cached across multiple calls in the same example but not across examples.
Source: https://www.relishapp.com/rspec/rspec-core/v/3-5/docs/helper-methods/let-and-let
那么您的控制器规格将如下所示:
...
let(:invalid_contact) { create(:contact, name: nil) }
context "with invalid attributes" do
it "does not create new contact" do
post :create, contact: attributes_for(invalid_contact)
expect(Contact.count).to eq(0)
end
end
...
这样 #post
动作 params
是从 invalid_contact
或者正如@fanta 在评论中建议的那样,您可以向您的工厂添加一个 trait
。我更喜欢我的方法,因为其他人看你的代码就会知道为什么 invalid_contact
应该无效而不看 :contacts
工厂