"Elgsena paremtas" programavimas(angl. Behaviour Driven Development). II dalis.
Posted by Saulius Grigaitis 17/05/2007 at 22h25
Sveiki! Pagaliau laisva valanda dar vienam įrašui apie BDD. Šįkart testuosime view'sus. RSpec suteikia galimybę juos testuoti, tad parodysiu kaip tai padaryti. Visų pirma reikia suprasti kas yra mock'ai ir stub'ai. Labai trumai - tai mechanizmai, kurie geba imituoti objektus, t.y. sukonstruojamas klasės egzempiorius, deklaruojami jo metodai ir tų metodų gražinami objektai. Iš esmės, tai tuščios juodos "dėžės", kurios sugeba priimti "signalus" ir į juos "sureaguoti", t.y. jam galima kviesti metodą ir gauti reikšmę. Rekomenduojama naudoti šį mechanizmą, nes tada visiškai atsirišama nuo kitų programos komponentų, kaip kontrolerių ar modelių. Kartu apsisaugoma nuo modelių pasikeitimo, t.y. naudojant realius modelius , atlikus pakeitimus juose, greičiausiai nugrius ir testas. Be abejo, šis mechanizmas leidžia rašyti view'sų testus dar neturint nei parašytų modelių, nei kontrolerių, iš kitos pusės, būtų visai neblogai matyti kaip modelio pakeitimas paveikė likusią programą, tad realus modelių ir mock'ų/stub'ų naudojimas priklauso nuo konkrečios situacijos. Susigeneruojam kontrolerį RSpec'o pagalba:$./script/generate rspec_controller notebooks/index require File.dirname(__FILE__) + '/../../spec_helper'
describe "/notebooks/index", :behaviour_type => :view do
before(:each) do
end
it "should have p tag with text 'My Notebook'" do
render 'notebooks/index'
response.should have_tag('p', 'My Notebook')
end
end
$ ruby notebooks/index_view_spec.rb
F
1)
'/notebooks/index should have p tag with text 'My Notebook'' FAILED
Expected at least 1 elements, found 0.
<false> is not true.
notebooks/index_view_spec.rb:10:
notebooks/index_view_spec.rb:3:
Finished in 0.07152 seconds
1 example, 1 failure #app/views/notebooks/index.rhtml
<p>My Notebook</p> $ ruby notebooks/index_view_spec.rb
.
Finished in 0.056177 seconds
1 example, 0 failures require File.dirname(__FILE__) + '/../../spec_helper'
describe "/notebooks/index", :behaviour_type => :view do
before(:each) do
#susikonstruojam mock'ą
@notebook = mock_model(Notebook)
#panaudojam stub mechanizmą tam, kad @notebook galėtų reaguoti į "pages" metodą gražindamas 100
@notebook.stub!(:pages).and_return(100)
#naudojam assigns mechanizmą tam, kad galėtume @notebook pasiekti view'se
assigns[:notebook] = @notebook
end
it "should have p tag with text 'My Notebook has 100 pages'" do
@notebook.should_receive(:pages).exactly(1).times.and_return(100)
render 'notebooks/index'
response.should have_tag('p', 'My Notebook has 100 pages')
end
end $ ruby notebooks/index_view_spec.rb
F
1)
'/notebooks/index should have p tag with text 'My Notebook has 100 pages'' FAILED
<"My Notebook has 100 pages"> expected but was
<"My Notebook">.
<false> is not true.
notebooks/index_view_spec.rb:13:
notebooks/index_view_spec.rb:3:
Finished in 0.072341 seconds
1 example, 1 failure
<p>My Notebook has <%= @notebook.pages %> pages</p> $ ruby notebooks/index_view_spec.rb
.
Finished in 0.059683 seconds
1 example, 0 failures 
