karhatsu / hirviurheilu

Hirviurheilu - tulospalvelu Metsästäjäliiton urheilulajeille
http://www.hirviurheilu.com
4 stars 1 forks source link

summat viestiin #33

Closed jkpj closed 13 years ago

jkpj commented 13 years ago

sakkojen summat viestijoukkueille

karhatsu commented 13 years ago

TESTIEN RAKENTEESTA Speksien perusrakenne näyttää oikein hyvältä. Mutta nyt otetaan taas seuraava askel kohti parempaa testikoodia:

Tapa jolla olet testit alustanut, luo turhan riippuvuussuhteen eri luokkien välille. Jos nimittäin käy niin, että relay_competitor.estimate_penalties-metodin toiminta muuttuu, se rikkoo turhaan team-puolen testin, vaikka itse summan laskenta olisikin säilynyt ennallaan. Kun puhutaan siitä, että TDD ja yksikkötestit yleensä aiheuttavat hirveän ylläpitovaivan testien suhteen, niin tässä on kyse juuri siitä. Ne eivät aiheuta, jos testit rakennetaan oikein.

Parempi ratkaisu olisi mockata (http://en.wikipedia.org/wiki/Mock_object) relay_competitor-olioiden käyttäytyminen. Meitähän ei kiinnosta se, kuinka penaltit lasketaan vaan se, miten summa lasketaan. Tämä näkyy oireena mm. siinä, kun olet joutunut tekemään kaksi erillistä nil-tapausta (jotka kyllä muuten ovat oikein hienosti tehty):

Nämä pitäisi mielummin korvata yhdellä: it "should return nil if at least one competitor is missing estimate penalties (syystä tai toisesta)" do

Ja toteutus voidaan hoitaa mockaamalla ja stubbaamalla tähän tyyliin:

before do @team = Factory.create(:relay_team) # relay:ta ei tässä tarvita ollenkaan c1 = mock_model(RelayCompetitor, :estimate_penalties => 10) c2 = mock_model(RelayCompetitor, :estimate_penalties => nil) @team.stub!(:relay_competitors).and_return([c1, c2]) end

Nyt kun team-luokassa kutsut relay_competitors, niin se palauttaa nuo kaksi mock-objektia. Kun sitten kutsut, niille olioille estimate_penalties-metodia, niin metodi palauttaa 10 tai nil riippuen oliosta.

Korostaakseni mockauksen periaatetta laitoin ihan tahallani esimerkkiin estimate_penalties-metodin palauttamaan jotain sellaista, mitä se ei todellisuudessa koskaan palauttaisi. Mutta on nimenomaan tärkeää huomata, että summametodin ei kuulu ottaa kantaa siihen, miten sakot lasketaan. Voihan vaikka olla, että säännöt joskus muuttuvat, jolloin 10 sakkoa on mahdollista. Ja tässäkin tilanteessa summa lasketaan edelleen siten kuin aiemminkin.

MÄÄRITTELYISTÄ Sitten sisällöstä sellainen pohdinta, että olin itse ajatellut näyttää myös keskeneräiset summat. Eli jos vaikkapa 2/4 osuutta on tiedossa, niin näytetään summana noiden kahden osuuden sakot. Tuloslistassahan ei kuitenkaan näy joukkueen yhteisaikaa, joten kaikki varmastikin ymmärtävät, että summakaan ei ole lopullinen. Määrittely olisi siis: it "should return sum of competitors' estimate penalties so that nil refers to 0 penalties"

Jos olet samaa mieltä, niin tässä vinkki koodiin: Käytä to_i-metodia. Jos on nil_objekti.to_i, se palauttaa 0.

karhatsu commented 13 years ago

Täältä vielä lisätietoa RSpec:n (ja cucumberin) mockeista ja stubeista: https://github.com/rspec/rspec-mocks