2012-02-12 20 views
5

Tengo modelos: Publicación y Usuario (Devise). Estoy probando el controlador Post.Prueba del controlador con RSpec, Devise, Factory Girl

describe "If user sign_in" do 

    before(:all){ 
    @user = Factory(:user) 
    } 

    it "should get new" do 
    sign_in @user 
    get 'new' 
    response.should be_success 
    response.should render_template('posts/new') 
    end 

    it "should create post" do 
    sign_in @user 
    post 'create', :post => Factory(:post) 
    response.should redirect_to(post_path(:post)) 
    end 
end 

Pero la segunda prueba falla:

Failure/Error: post 'create', :post => Factory(:post) ActiveRecord::RecordInvalid: Validation failed: Email has already been taken, Email has already been taken, Username has already been taken

¿Cómo puedo solucionar esto?

Respuesta

7

Necesita una herramienta para limpiar su base de datos entre pruebas. Porque debería poder ejecutar cada prueba con una base de datos limpia. Estoy usando database_cleaner, es una joya bastante famosa y funciona muy bien. Es fácil de configurar también. Un ejemplo del archivo README (relacionado con RSpec):

RSpec.configure do |config| 

    config.before(:suite) do 
    DatabaseCleaner.strategy = :transaction 
    DatabaseCleaner.clean_with(:truncation) 
    end 

    config.before(:each) do 
    DatabaseCleaner.start 
    end 

    config.after(:each) do 
    DatabaseCleaner.clean 
    end 

end 
+3

Cuando incluyo tu código en spec_helper. Obtuve un error Error/Error: no se puede encontrar la línea coincidente desde el backtrace ActiveRecord :: StatementInvalid: SQLite3 :: SQLException: no puede iniciar una transacción dentro de una transacción: begin transaction – Mike

+0

no necesita otra joya para esto. – coneybeare

+3

Encontré que la solución de excepción SQLite era eliminar 'clean_with (: truncation)' y cambiar la estrategia completamente a 'DatabaseCleaner.strategy =: truncation' – Dan

9

No necesita otra joya para esto. FactoryGirl ha incorporado ayudantes dinámicos para esto. Sugiero ver el corto Railscast sobre esto. Aquí hay un fragmento de cómo funciona:

FactoryGirl.define do 
    factory :user do 
    sequence(:username) { |n| "foo#{n}" } 
    password "foobar" 
    email { "#{username}@example.com" } 
+1

hmmm, un enlace al contenido pago ... no parece ser el más útil de respuestas ... – botbot

+18

Si usted es un desarrollador de rieles y no utiliza Railcasts, entonces lo está haciendo mal. – coneybeare

+0

, pero si usted es un desarrollador de TRUE Rails, primero debe vincular el contenido gratuito y luego sugerir el pago. – Aleks

Cuestiones relacionadas