homeASCIIcasts

12: Refactoring del nome utente Parte 3 

(view original Railscast)

Other translations: En Es Fr

Other formats:

Written by Andrea Salicetti

L’ l’ultimo episodio e il penultimo si sono focalizzati sul refactoring e il test. Nell’ultimo episodio abbiamo rivisto il codice del nostro modello, ma i test su quest’ultimo erano rimasti un po’ imperfetti. Vediamo cosa possiamo fare per sistemarli.

    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
  

I test per la classe User.

Abbiamo tre test e un sacco di duplicazioni fra di loro. Per ogni test creiamo un nuovo User e lo confrontiamo con una stringa. Per rimuovere questa duplicazione creeremo un metodo che crea un nuovo User e restituisce il suo full_name.

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

Il nuovo metodo (non di test) della classe UserTest.

Ora, ognuno dei nostri test può sfruttare questo codice comune ed essere semplificato in modo tale da apparire così:

  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
  

Il test semplificato per uno User con iniziale di secondo nome.

Al solito, la prova che il nostro refactoring è corretto, è che i test hanno tutti ancora successo.

  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
  

I test rivisti hanno ancora successo.

Ora che i nostri test sono a posto, possono essere spostati in un singolo metodo con tre assertion. L’unico problema nel fare ciò, è che se una di queste assertion fallisce, diventa difficile sapere quale. Possiamo però aggiungere un messaggio ad ogni assertion proprio per ovviare a questo inconveniente, in modo tale che ogni controllo sia ben indentificabile quando fallisce. La nostra classe di test finale appare così:

  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 dopo la revisione.

Negli ultimi tre episodi abbiamo creato test unitari e li abbiamo migliorati, insieme al codice che questi andavano a testare, per lasciare entrambi nella forma più leggibile e mautenibile possibile. Sebbene l’esempio visto sia stato relativamente semplice, dovrebbe comunque convincervi dei benefici derivanti dalla pratica dei test e del refactoring del codice in Ruby on Rails.