这对我没有意义,希望有人可以提供帮助。在使用工厂创建用户时,我遇到了单个测试失败(看似类似的测试通过)。
在我的user_spec.rb测试文件中,用户最初是这样创建的。使用这种初始化方法,所有测试都通过了。
用户创作
user_spec.rb (没有工厂)
describe User do
before do
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar", password_confirmation: "foobar",
username: "username")
end
该应用程序的大多数其他测试都使用工厂。因此,决定用工厂取代上述。
user_spec.rb (带工厂)
describe User do
before do
@user = FactoryGirl.create(:user)
end
FACTORY
工厂看起来像这样。
factories.rb
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Person #{n}" }
sequence(:email) { |n| "person_#{n}@example.com" }
password "foobar"
password_confirmation "foobar"
sequence(:username) { |n| "username_#{n}" }
测试失败
使用工厂创建用户时,这是测试失败。
user_spec.rb
Failures:
1) User when email address is already taken
Failure/Error: it { should_not be_valid }
expected valid? to return false, got true
# ./spec/models/user_spec.rb:101:in `block (3 levels) in <top (required)>'
Finished in 12.61 seconds
178 examples, 1 failure, 2 pending
TEST
以下是切换到工厂时测试失败的部分。
describe "when email address is already taken" do
before do
user_with_same_email = @user.dup
user_with_same_email.email = @user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
检查用户和USER.DUP
我的第一个想法是在工厂创建的用户可能正在使用.dup导致问题。以下是@user和@ user.dup在上面的测试中使用时的输出(通过将行puts @user.inspect
和puts user_with_same_email.inspect
添加到describe块中。这两个puts
都是在user_with_same_email.save
之后。
没有工厂(测试通过)
@user
#<User id: nil, name: "Example User", email: "user@example.com",
created_at: nil, updated_at: nil,
password_digest: "$2a$04$I/71i.fpTwfp4PqRwAvU4eUEjEkW/wubx6uVBqfNBShq...",
remember_token: nil, admin: false, username: "username">
user_with_same_email
#<User id: 1178, name: "Example User", email: "USER@EXAMPLE.COM",
created_at: "2012-04-24 06:01:07", updated_at: "2012-04-24 06:01:07",
password_digest: "$2a$04$I/71i.fpTwfp4PqRwAvU4eUEjEkW/wubx6uVBqfNBShq...",
remember_token: "rMS9jM0d4lobLc-A-pTTqA", admin: false, username: "username">
WITH FACTORY(测试失败)
@user
#<User id: 739, name: "Person 67", email: "person_67@example.com",
created_at: "2012-04-24 05:54:28", updated_at: "2012-04-24 05:54:28",
password_digest: "$2a$04$n4tToBVM2elz92cfHPKvte6dfHSBj4jDxG.w6DyKtGUR...",
remember_token: "fy2iifmhXVTFa1__d1dBJg", admin: false, username: "username_67">
user_with_same_email
#<User name: "Person 67", email: "PERSON_67@EXAMPLE.COM",
created_at: nil, updated_at: nil,
password_digest: "$2a$04$n4tToBVM2elz92cfHPKvte6dfHSBj4jDxG.w6DyKtGUR...",
remember_token: "fy2iifmhXVTFa1__d1dBJg", admin: false, username: "username_67">
上面提到的是@user在没有使用工厂的情况下尚未保存,而在使用工厂时@user被保存。在这种情况下,我只是没有看到它如何影响测试。
任何帮助将不胜感激。谢谢!
(上面的代码来自Michael Hartl的Rails教程,我正在研究本教程末尾提到的app feature extensions中的一些内容。)
答案 0 :(得分:4)
工厂将记录放入数据库中。 User.new直到保存为止。原始测试不会检查是否创建了user_with_same_email,而是因为电子邮件存在而无法创建“it”(主题{@user})。在对@user进行更改后,我不得不重写测试:
describe "when email address is already taken" do
let (:user_with_same_email) { @user.dup }
specify { user_with_same_email.should_not be_valid }
end
答案 1 :(得分:1)
谢谢埃里克。以你的考试为基础......
原始测试还测试了区分大小写和唯一性。这个测试通过并且似乎可以解决问题。有什么想法吗?
describe "when email address is already taken" do
let(:user_with_same_email) { @user.dup }
before do
user_with_same_email.email = @user.email.upcase
user_with_same_email.save
end
specify { user_with_same_email.should_not be_valid }
end