从初始化属性切换到Factory时,rspec测试失败

时间:2012-04-24 06:15:38

标签: ruby-on-rails-3 testing rspec factory-bot railstutorial.org

这对我没有意义,希望有人可以提供帮助。在使用工厂创建用户时,我遇到了单个测试失败(看似类似的测试通过)。

在我的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.inspectputs 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中的一些内容。)

2 个答案:

答案 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