homeASCIIcasts

12: Refactorisation : Troisième 

(view original Railscast)

Other translations: En It Es

Other formats:

Written by Adrien Giboire (adriengiboire.com)

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.