Rails 3 + Rspec 2:验证失败:已经收到电子邮件

时间:2011-04-08 21:54:45

标签: ruby-on-rails-3 rspec rspec2 factory-bot rspec-rails

我有2个模型,UserBucketUser has_many BucketsBucket belongs_to一个User

factories.rb中,我有:

Factory.define :user do |user|
  user.email  "teste@test.com"
  user.password               "foobar"
  user.password_confirmation  "foobar"
end


Factory.sequence :email do |n| 
  "person-#{n}@example.com"
end

Factory.define :bucket do |bucket|
  bucket.email        "user@example.com"
  bucket.confirmation false
  bucket.association :user
end

我有一个login_user模块,如下所示:

def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      @user = Factory.create(:user)
      #@user.confirm!
      sign_in @user
    end
  end

我正在使用Spork和Watch,我的Buckets_controller_spec.rb就像:

一样简单
describe "User authenticated: " do

   login_user  

   @bucket = Factory(:bucket)

   it "should get index" do
     get 'index'
     response.should be_success
   end
...
end

错误始终相同:

Failures:

  1) BucketsController User authenticated: should get index
     Failure/Error: Unable to find matching line from backtrace
     ActiveRecord::RecordInvalid:
       Validation failed: Email has already been taken
     # ./lib/controller_macros.rb:12:in `block in login_user'

只有当我拥有Factory(:bucket)时才会发生这种情况。当我不添加Factory(:bucket)时,登录正常。

总是一样的错误。我尝试向用户添加:email => Factory.next(:email),但没有成功。

编辑:

rails c test

ruby-1.9.2-p180 :019 > bucket = Factory(:bucket, :email => "hello@hello.com")
    ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

    ruby-1.9.2-p180 :018 >   Bucket.create(:email => "hello@hello.com")
     => #<Bucket id: 2, email: "hello@hello.com", confirmation: nil, created_at: "2011-04-08 21:59:12", updated_at: "2011-04-08 21:59:12", user_id: nil> 

编辑2:

我发现错误在关联中,但是,我不知道如何修复它。

  bucket.association :user

3 个答案:

答案 0 :(得分:6)

当您使用关联定义工厂时,无论何时使用工厂,都需要向工厂提供要关联的对象。

这应该有效:

describe "User authenticated: " do
  login_user
  @bucket = Factory(:bucket, :user => @user)

  it "should get index" do
    get 'index'
    response.should be_success
  end
end

这样,女工就知道要制作一个与@user相关的桶。

答案 1 :(得分:5)

在您的用户工厂中尝试:

Factory.define :user do |f|
  f.sequence(:email) { |n| "test#{n}@example.com" }
  ...
end

我认为这可能是你的问题。当您使用f.email = "anyvalue"时,它每次都会使用该值。我看到你试图在下一个块中创建一个序列,但我不确定序列是否被使用。

另外 - 请注意,如果您因崩溃或某些事情而中断测试,有时虚假的测试数据可能会留在测试数据库中而不是被回滚。

如果一次工作一次然后退出工作,我尝试的第一件事就是重置测试数据库。

rake db:test:prepare

这将清除一切。

如果这不起作用,请告诉我,我会再看看!

答案 2 :(得分:0)

如果有人最近收到你的意见。尝试使用Database Cleaner

了解更多信息:RailsTutorial - chapter 8.4.3 - Test database not clearing after adding user in integration test