"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
Ir paprastas spec'as:
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

Nepraeinam testo:
$ 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
taisom view'są:
#app/views/notebooks/index.rhtml
<p>My Notebook</p>
šikart pasisekė kur kas geriau:
$ ruby notebooks/index_view_spec.rb
.

Finished in 0.056177 seconds

1 example, 0 failures
Tvarkoj, dabar kiek sudėtingiau - naudojam mock'us/stub'us:
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
Nepavyko:
$ 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
taisom view'są:
<p>My Notebook has <%= @notebook.pages %> pages</p>
jėėė..veikia!
$ ruby notebooks/index_view_spec.rb
.

Finished in 0.059683 seconds

1 example, 0 failures
Laukite tęsinio!

no comments | no trackbacks

Comments

Trackbacks

Use the following link to trackback from your own site:
http://www.rubyonrails.lt/trackbacks?article_id=13

(leave url/email »)

reCaptcha

   Comment Markup Help Preview comment