2010-10-04 9 views
32

¿Cómo desactivo los dispositivos transaccionales para una sola especificación (o escenario de Steak) con RSpec 2? Probé algunas cosas encontradas en la web sin ningún éxito.Desactivar dispositivos transaccionales para una especificación con RSpec 2

Esto lleva a una excepción de método indefinido.

 
describe "MyClass without transactional fixtures" do 
    self.use_transactional_fixtures = false 
    ... 
end 

Esto simplemente no hace nada (accesorio transaccional está todavía en):

 
describe "MyClass without transactional fixtures" do 
    RSpec.configure do |config| 
    config.use_transactional_fixtures = false 
    end 
    ... 
end 

¿Qué más puedo probar?

+0

está realmente conectado para querer eso. porque no puedes saber lo que tienes en tu base de datos. – shingara

+0

Espero que no sea cierto para su código, también ;-) Pero en serio, para algunos escenarios de prueba, debe desactivar los dispositivos transaccionales. Por ejemplo, como en mi caso, para probar Thinking Sphinx. Sphinx necesita actualizar el índice de búsqueda desde el "exterior". Por lo tanto, debe conocer el contenido de la base de datos en un momento específico. – Zardoz

+0

Solo una cosa para notar; Al menos en mi entorno (Rails4 rspec 2) si por alguna razón incluye el rspec/rails_helper en cualquiera de sus archivos rspec, causará que cualquier prueba posterior al mismo en el paquete o en los archivos subsiguientes se ejecute transaccionalmente de nuevo. –

Respuesta

7

Esto solía ser un error (vea ticket #197), pero parece que ahora estoy bien. Simplemente no sé si funcionará en una base por prueba (probablemente no). Si desea hacer esto, puede deshabilitar dispositivos transaccionales globalmente poniendo config.use_transactional_fixtures = false en el spec_helper.rb y use DatabaseCleaner para configurar eso.

He tenido un problema similar al probar páginas con javascript en el navegador (un escenario que no funciona con dispositivos transaccionales). Así es como me las arreglé para trabajar alrededor de ella: http://github.com/lailsonbm/contact_manager_app

+1

Gracias por indicarme el boleto, Lailson. Respuesta aceptada :-) También uso una solución ya que no me gusta desactivar los dispositivos transaccionales globalmente (demasiado lento). Simplemente hago una MyClass.connection.commit_db_transaction() después de que se crearon los objetos. Luego hago la prueba y luego borro las entradas de la base de datos. Eso funciona bien, y todas las demás pruebas aún usan la función transaccional. – Zardoz

+0

Agradable. Como dije, puedes hacer esto limpiamente con DatabaseCleaner (mira el README github repo que señalé para saber cómo hacer esto).Pero su solución también es viable, solo un poco propensa a errores. Pero si está funcionando y estás satisfecho, genial ... =) –

+0

Intenté 'MyClass.connection.commit_db_transaction' pero dejó la conexión en un estado extraño donde creía que tenía una transacción abierta, pero no fue así. Esto hizo que ciertos comandos de registro activos no funcionaran y también dio lugar a advertencias. Esto pareció solucionar ese problema, en realidad cerró la transacción en el archivo db y actualizó la conexión para saber que ya no tenía una transacción abierta: MyClass.connection..transaction_manager.commit_transaction – nbrustein

25

Yo suelo añadir un ayudante así:

def without_transactional_fixtures(&block) 
    self.use_transactional_fixtures = false 

    before(:all) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    yield 

    after(:all) do 
    DatabaseCleaner.strategy = :transaction 
    end 
end 

que me permite apagar los accesorios transaccionales para un bloque específico en las especificaciones:

describe "doing my thing" do 
    without_transactional_fixtures do 
    it "does something without transaction fixtures" do 
     ... 
    end 
    end 
end 
+0

¿Estás seguro de que funciona? He intentado aquí probar algo que estaba usando transacciones de rieles y no funcionó :( – Guilherme

+2

Puedes simplemente cambiar la estrategia DatabaseCleaner.strategy en un bloque antes/después de tus especificaciones también. –

7

Lo he hecho de esta manera, con database_cleaner, para probar el código que usa transacciones (que entrarán en conflicto con las soluciones transaccionales o cualquier otra estrategia para realizar pruebas transaccionales, por ejemplo, DatabaseCleaner.strategy =: truncation o: transaction):

# spec_helper.rb 
config.use_transactional_fixtures = false 
config.around(:each, :testing_transactions => true) do |ex| 
    DatabaseCleaner.strategy = nil 
    ex.run 
    DatabaseCleaner.strategy = :truncation 
end 

y en mis casos de prueba:

it "should not save if one of objects are invalid", :testing_transactions => true 
0

No estoy seguro si eso se aplica a RSpec2, pero funciona bien con 3.

config.use_transactional_fixtures = true 
config.around(:each, use_transactional_fixtures: false) do |example| 
    self.use_transactional_tests = false 
    example.run 
    self.use_transactional_tests = true 
end 

Mente (la opción rspec-carriles) use_transactional_fixtures y use_transactional_tests (opción de los accesorios de grabación activa).

Cuestiones relacionadas