#12 Refactoring User Name Part 3
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
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.