mercredi 22 février 2017

Error during auto-generated rails test

I'm learning tests on Rails and some auto-generated tests are failing. One of them is "should update usuario", which looks very simple:

require 'test_helper'
class UsuariosControllerTest < ActionController::TestCase
  setup do
    @usuario = usuarios(:fulano)
  end
  ...
  test "should update usuario" do
    patch :update, id: @usuario, usuario: { email: "novo@email.com", nome: "Novo Nome" }
    assert_redirected_to usuario_path(assigns(:usuario))
  end
end

The test error:

  1) Failure:
UsuariosControllerTest#test_should_update_usuario [/home/mariana/projetos/.rd/desafio/test/controllers/usuarios_controller_test.rb:39]:
Expected response to be a <redirect>, but was <200>

I googled it and it seems that the update is failing, so instead of being redirected to @usuario, the program redirects back to the form, resulting in the 200 response instead of 302.

Looking into log/test.log I found:

--------------------------------------------------
UsuariosControllerTest: test_should_update_usuario
--------------------------------------------------
  Usuario Load (0.1ms)  SELECT  "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = $1 LIMIT 1  [["id", 13365528]]
  Processing by UsuariosController#update as HTML
  Parameters: {"usuario"=>{"email"=>"novo@email.com", "nome"=>"Novo Nome"}, "id"=>"13365528"}
  Usuario Load (0.2ms)  SELECT  "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = $1 LIMIT 1  [["id", 13365528]]
   (0.2ms)  SAVEPOINT active_record_1
  Usuario Exists (0.4ms)  SELECT  1 AS one FROM "usuarios" WHERE (LOWER("usuarios"."email") = LOWER('novo@email.com') AND "usuarios"."id" != 13365528) LIMIT 1
   (0.1ms)  ROLLBACK TO SAVEPOINT active_record_1
  Rendered usuarios/_form.html.erb (3.0ms)
  Rendered usuarios/edit.html.erb within layouts/application (3.4ms)
  Usuario Load (0.6ms)  SELECT  "usuarios".* FROM "usuarios" WHERE "usuarios"."id" IS NULL LIMIT 1
  Completed 200 OK in 15ms (Views: 9.8ms | ActiveRecord: 1.5ms)
   (0.2ms)  ROLLBACK

Which confirms the assumption that the 200 response is due to rails reverting back to usuarios/_form.html.erb. What's strange is this line:

Usuario Exists (0.4ms)  SELECT  1 AS one FROM "usuarios" WHERE (LOWER("usuarios"."email") = LOWER('novo@email.com') AND "usuarios"."id" != 13365528) LIMIT 1    

More specifically:

... AND "usuarios"."id" != 13365528) ...

Why is the test looking for a user that contains the updated e-mail, but not the ID of the user that was updated? Running this line straight into the database indeed returns nothing, but running it without the ID filter returns the correct entry.

Why is Rails looking for an entry with a different ID after an update, when it should look for the entry with that same ID to check for changes.

Aucun commentaire:

Enregistrer un commentaire