12: Refactorisation : Troisième
Other formats:
Les deux derniers épisodes étaient centrés sur la refactorisation et les tests. A la fin du dernier épisode, nous avons refactorisé notre modèle, mais les tests étaient quelques peu en bazar. Voyons comment les organiser un peu mieux.
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
Les tests pour la classe User.
Nous avons trois tests et il y a beaucoup de duplications. Pour chaque test nous créons un nouvel utilisateur User et le comparer à une chaine. Pour supprimer la duplication nous allons créer une méthode qui crée un nouvel User et renvoyer son full_name.
def full_name(first, middle, last) User.new(:first_name => first, :middle_initial => middle, :last_name => last).full_name end
La nouvelle méthode pour la classe UserTest.
Maintenant, chaqu'un de nos tests peut être simplifiés et vont ressembler à ceci :
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
Le test simplifié pour un User avec une initiale.
Bien sûr, la preuve que notre refactorisation fonctionne est que nos tests réussissent tous.
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
Les tests unitaires passent toujours.
Maintenant que nos tests sont simples, ils peuvent être déplacés dans un test unique avec trois assertions. L'unique problème en faisant ça c'est que si une des assertions d'un test échoue c'est difficile de savoir laquelle c'était. On peut ajouter un message pour chaque assertion pour identifier celle qui échoue. Notre classe de test ressemble à ça :
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 classe finale UserTest refactorisée.
À travers les trois derniers épisodes, nous avons créé des tests unitaires et les avons refactorisé avec le code qu'ils testent pour arriver à quelque chose de plus facile à lire et à maintenir. Bien que ce soit un exemple simple, il devrait vous persuader des bénéfices de tester et refactoriser votre code.



