2011-06-12 12 views
19

Tengo dificultades para probar el método de actualización en Rails. Estoy usando el marco de prueba integrado estándar (test::unit) y Rails 3.0.8. He creado una aplicación mínima para probar esto ahora, pero no puedo hacer que funcione. Aquí es lo que hago:Cómo probar el método de actualización en Rails

puedo crear una nueva aplicación de carriles en blanco:

rails new testapp 

Crear un modelo llamado Colección:

rails generate model collection name:string 

Run rake db: migrate:

rake db:migrate 

Crea un controlador llamado Colecciones con un método de actualización:

rails generate controller collections update 

En collection_controller.rb I añadir este método mínimo actualización:

def update 
    @collection = Collection.find(params[:id]) 
    @collection.update_attributes(params[:collection]) 
end 

Los accesorios de la prueba son los valores predeterminados (collections.yml):

one: 
    name: MyString 

two: 
    name: MyString 

Luego añadir esto a la collection_controller_test. rb en funcional:

test "should update collection" do 
    put :update, :id => collections(:one), :collection => {:name => 'MyString2'} 
    assert_equal "MyString2", collections(:one).name 
end 

Cuando ejecuto la prueba:

rake test:functionals 

Es un error con este mensaje:

test_should_update_collection(CollectionsControllerTest) [/Users/atle/Documents/Rails/testapp/test/functional/collections_controller_test.rb:6]: 
<"MyString2"> expected but was 
<"MyString">. 

Éstos son la salida de test.log:

[1m[36mSQL (0.2ms)[0m [1m SELECT name 
FROM sqlite_master 
WHERE type = 'table' AND NOT name = 'sqlite_sequence' 
[0m 
[1m[35mCollection Load (0.1ms)[0m SELECT "collections".* FROM "collections" WHERE "collections"."id" = 980190962 LIMIT 1 
Processing by CollectionsController#update as HTML 
Parameters: {"id"=>#<Collection id: 980190962, name: "MyString", created_at: "2011-06-12 13:14:13", updated_at: "2011-06-12 13:14:13">, "collection"=>{"name"=>"MyString2"}} 
[1m[36mCollection Load (0.2ms)[0m [1mSELECT "collections".* FROM "collections" WHERE "collections"."id" = 980190962 LIMIT 1[0m 
[1m[35mAREL (0.2ms)[0m UPDATE "collections" SET "name" = 'MyString2', "updated_at" = '2011-06-12 13:14:13.394135' WHERE "collections"."id" = 980190962 
Rendered collections/update.html.erb within layouts/application (1.5ms) 
Completed 200 OK in 9ms (Views: 4.5ms | ActiveRecord: 1.2ms) 

En el registro de lo que puedo ver el comunicado UPDATE, pero nunca ver una nueva declaración SELECT.

¿Podría alguien explicarme lo que estoy haciendo mal, por favor?

+2

+1 para una pregunta clara.Es bueno ver a un nuevo usuario haciendo una pregunta explícita con este nivel de detalle. Su problema definitivamente deriva de 'collections (: one)' en su aserción, que simplemente lee del accesorio nuevamente, en lugar de db. Cameron y Teddy tienen esto correcto a continuación. (Por cierto: fíjate en 'factory_girl' y dump fixtures enteramente ASAP. Son convenientes para empezar, pero luego es un lío horrible). – jdl

+0

Así que los accesorios y el db son dos ubicaciones distintas. Supuse que los dispositivos se leen en el archivo db al inicio y que las colecciones (: uno) leen desde el archivo db. Gracias por aclarar las cosas y voy a investigar esa factory_girl :) – Atle

Respuesta

13

Está recargando los datos del dispositivo en lugar de leer desde el archivo db. Pruebe algo como

assert_equal "MyString2", Collection.find(collections(:one)).name 

Puede que necesite especificar la identificación en el dispositivo.

Descargo de responsabilidad: No lo he probado.

+1

Esto funcionó, ahora mis pruebas funcionan, ¡gracias! – Atle

+0

No use el DB en la prueba si no lo necesita. No quiere probar si el DB funciona, ¿verdad? – schmijos

17

Usted puede hacer afirmaciones sobre la variable de instancia que se crea durante la respuesta HTTP:

test "should update collection" do 
    put :update, :id => collections(:one), :collection => {:name => 'MyString2'} 
    assert_equal "MyString2", assigns(:collection).name 
end 
+0

Tu sugerencia también funcionó, pero acepté la respuesta de Cameron, ya que él fue el primero;) ¡Gracias! – Atle

+0

Esta es la mejor respuesta, ya que no utiliza la base de datos. – schmijos

+0

Esta es la respuesta correcta. Collection.find (colecciones (: uno)) es feo. – hellion

2

Mi variante preferida de esta:

test "should update collection" do 
    coll = collections(:one) 
    put :update, :id => coll, :collection => {:name => "MyString2"} 
    assert_equal "MyString2", coll.reload.name 
end 

El truco assigns(:collection) en realidad no garantiza el registro fue salvado. Esto puede no ser un problema, o puede ser una sorpresa.

+0

Use 'asignaciones' si es posible. No necesita ninguna interacción de base de datos para lo que quiere probar. – schmijos

Cuestiones relacionadas