3

这对我来说毫无意义,希望有人能提供帮助。使用工厂创建用户时,我遇到了一次测试失败(似乎通过了类似的测试)。

在我的 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

工厂

工厂是这样的。

工厂.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

测试

这是切换到工厂时测试失败的部分。

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.inspectputs user_with_same_email.inspectdescribe 块中。这两个puts都在之后user_with_same_email.save)。

无工厂(测试通过)

@用户

#<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 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 教程,我正在研究他在教程末尾提到的一些应用程序功能扩展。)

4

2 回答 2

4

工厂将记录存入数据库。User.new 在保存之前不会。原始测试不检查是否创建了 user_with_same_email,而是因为电子邮件存在而无法创建“它”(主题 { @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
于 2012-04-24T17:22:53.243 回答
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
于 2012-04-24T20:45:42.990 回答