homeASCIIcasts

12: Refactoreando el nombre de usuario – Parte 3 

(view original Railscast)

Other translations: En It Fr

Other formats:

Written by Aldo Escudero (aldoescudero.com.ar)

En los ultimos dos episodios trabajamos refactoreando y haciendo testing. Al final del último episodio refactoreamos nuestro modelo, pero los tests estaban un poco desordenados. Veamos que podemos hacer para ordenarlos.

require 'test_helper'  
class UserTest < ActiveSupport::TestCase  
  test "full name without middle initial" do  
    user = User.new(:first_name => "John", :last_name => "Smith")  
    assert_equal 'John Smith', user.full_name  
  end  
  
  test "full name with middle initial" do  
    user = User.new(:first_name => "Paul", :middle_initial => "P", :last_name => "Hughes")  
    assert_equal 'Paul P. Hughes', user.full_name  
  end  
  
  test "full name with empty middle initial" do  
    user = User.new(:first_name => "John", :middle_initial => "", :last_name => "Jones")  
    assert_equal 'John Jones', user.full_name  
  end  
end  

Los tests para la clase User.

Tenemos tres tests y hay mucha duplicación en ellos. Para cada test creamos un nuevo usuario y lo comparamos con el valor de la cadena. Para eliminar la duplicación vamos a crear un método que crea un nuevo usuario y devuelve su nombre completo (full_name).

def full_name(first, middle, last)  
  User.new(:first_name => first, :middle_initial => middle, :last_name => last).full_name  
end  

El nuevo método “que no es un test” de la clase UserTest.

Ahora, cada uno de nuestros tests puede simplificarse para que se vea de la siguiente manera:

test "full name without middle initial" do  
  assert_equal "John Smith", full_name('John', nil, 'Smith')  
end  
  
test "full name with middle initial" do  
  assert_equal 'Paul P. Hughes', full_name('Paul', 'P', 'Hughes')  
end    
  
test "full name with empty middle initial" do  
  assert_equal "John Jones", full_name('John', '', 'Jones')  
end  

El test simplificado para un usuario con inicial del segundo nombre.

Por supuesto, que la prueba de que nuestro refactoreo ha funcionado es que los tests aun funcionan.

Laa-Laa:ep11 eifion$ autotest
loading autotest/rails
/opt/local/bin/ruby -I.:lib:test -rtest/unit -e "%w[test/unit/user_test.rb test/functional/users_controller_test.rb].each { |f| require f }" | unit_diff -u
Loaded suite -e
Started
...
Finished in 0.282538 seconds.

3 tests, 3 assertions, 0 failures, 0 errors

Los unit tests refactoreados aun pasan.

Ahora que nuestros tests son correctos, pueden ser movidos a un único test con tres asserts (afirmaciones). El único problema al hacer esto, es que si un assert en un test falla, es mas difícil saber cual es el que fallo. Podemos agregar un mensaje a cada assert para que lo identifique si falla. Nuestra clase UserTest quedaría de la siguiente forma:

require 'test_helper'  
  
class UserTest < ActiveSupport::TestCase  
  test "full name" do  
    assert_equal "John Smith", full_name('John', nil, 'Smith'), 'nil middle initial'  
    assert_equal 'Paul P. Hughes', full_name('Paul', 'P', 'Hughes'), 'P middle initial'  
    assert_equal "John Jones", full_name('John', '', 'Jones'), 'blank middle initial'  
  end  
  
  def full_name(first, middle, last)  
    User.new(:first_name => first, :middle_initial => middle, :last_name => last).full_name  
  end  
end  

La clase refactoreada final UserTest.

En los últimos tres episodios hemos creado testings unitarios y los hemos refactoreado con el código que testeaban, para dejar ambos en un estado mas legible y manejable. Mientras que esto fue un ejemplo relativamente simple, lo debería persuadir a ver los beneficios de testear y refactorear su código Ruby y Rails.