我有一个名为“Charity”的对象,我想确保每个慈善机构都有一个独特的名称,不幸的是我得到了以下失败的测试,我怀疑这是我工厂的问题:
Failures
1) Charity name is already taken
Failure/Error: it { @charity_with_same_name.should_not be_valid }
NoMethodError:
undefined method 'valid?' for nil:NilClass
...
慈善对象属于用户对象。这是charity.rb:
class Charity < ActiveRecord::Base
attr_accessible :name, :description, :summary
belongs_to :user
validates :name, presence: true, uniqueness: { case_sensitive: false }, length: { maximum: 40 }
validates :summary, presence: true, length: { maximum: 140 }
validates :description, presence: true
validates :user_id, presence: true
default_scope order: 'charities.created_at DESC'
end
以下是charity_spec.rb的相关部分:
require 'spec_helper'
describe Charity do
let(:user) { FactoryGirl.create(:user) }
#before { @charity = user.charities.build(summary: "Lorem ipsum") }
before { @charity = user.charities.build(FactoryGirl.attributes_for(:charity)) }
# this makes sure that all the attributes for charity are set, whereas
#the previous code only sets the "summary" attribute
subject { @charity }
...
describe "name is already taken" do
before do
charity_with_same_name = @charity.dup
charity_with_same_name.name = @charity.name.upcase
charity_with_same_name.save
end
it { @charity_with_same_name.should_not be_valid }
end
...
这是factory.rb:
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Person #{n}" }
sequence(:email) { |n| "person_#{n}@example.com" }
password "foobar"
password_confirmation "foobar"
...
factory :charity do
sequence(:name) { |n| "charity #{n}" }
sequence(:summary) { |n| "summary #{n}" }
sequence(:description) { |n| "description #{n}" }
end
end
我做错了什么?
答案 0 :(得分:0)
您可以在前一个块中将charity_with_same_name
变为实例变量(将charity_with_same_name
更改为@charity_with_same_name
),然后将it { @charity_with_same_name.should_not be_valid }
更改为specify { @charity_with_same_name.should_not be_valid }
以使其变为通过。
问题是@charity_with_same_name
不存在,因为您尚未对其进行初始化。您只设置了charity_with_same_name
。此外,由于subject { @charity }
,it
引用@charity
,因此it { @charity_with_same_name.should_not be_valid }
在这里没有意义。
编辑:除了执行上述操作之外,您还需要在@charity.save
块中添加行before
(在行charity_with_same_name = @charity.dup
之前)。这是必要的,因为您的重复记录将通过验证(当它不应该时),尽管它与@charity
具有相同的名称,因为@charity
尚未保存到数据库中。保存慈善机构后,验证测试将检查数据库并查看该名称是否已被删除。