Hi Hans,
I rewrote my specs the way you suggested and now everything works!
For those who are interested, here's how the code looks like now (after
following Hans' tips).
> a) writing a separate spec for the partial _question_for_candidate
require File.dirname(__FILE__) + '/../../spec_helper'
module QuestionForCandidatePartialHelper
def get_question_type_mock(type)
mock_model(QuestionType, {:name => type})
end
def render_question_for_candidate_partial
render(:partial => 'survey/question_for_candidate', :locals =>
{:question => @question})
end
end
describe 'partial survey/_question_for_candidate.rhtml' do
include QuestionForCandidatePartialHelper
before(:each) do
@question = mock_model(Question, {
:id => 1,
:description => 'The description',
:position => 4,
:alternatives => [mock_model(Alternative, {:id => 1, :description =>
'Alternative 1 Description'})],
})
@question_type_exclusive = get_question_type_mock('exclusive')
@question_type_multiple = get_question_type_mock('multiple')
end
it 'should render the top of the template no matter the question type' do
@question.stub!(:question_type).and_return(@question_type_exclusive)
render_question_for_candidate_partial
response.should have_tag('div.question.question-4') do
with_tag('.heading .number', '4.')
with_tag('.heading .description', @question.description)
end
end
it 'should render an exclusive-answer question' do
@question.stub!(:question_type).and_return(@question_type_exclusive)
render_question_for_candidate_partial
response.should have_tag('div.question.question-4') do
with_tag('input[type=?]', 'radio')
without_tag('input[type=?]', 'checkbox')
end
end
it 'should render a multiple-answer question' do
@question.stub!(:question_type).and_return(@question_type_multiple)
render_question_for_candidate_partial
response.should have_tag('div.question.question-4') do
with_tag('input[type=?]', 'checkbox')
without_tag('input[type=?]', 'radio')
end
end
end
> b) write a separate spec for the helper that renders the question
require File.dirname(__FILE__) + '/../spec_helper'
describe SurveyHelper do
before(:each) do
@question = mock_model(Question)
end
it 'should render a question using the question_for_candidate partial' do
self.should_receive(:render).with(:partial => 'question_for_candidate',
:locals => {:question => @question})
render_question(@question)
end
end
> b) in the view spec for /survey/show use should_receive to determine
that the helper is actually being called
require File.dirname(__FILE__) + '/../../spec_helper'
describe '/survey/show' do
before(:each) do
assigns[:configurations] = {:survey_name => 'Whatever'}
@positions = [4, (9..22).to_a].flatten
@questions = Array.new
@positions.each do |position|
@questions[position] = mock_model(Question, {
:id => 1,
:description => 'The description',
:position => 4,
:alternatives => [mock_model(Alternative, {:id => 1, :description =>
'Description'})],
:question_type => mock_model(QuestionType, {:name => 'exclusive'})
})
end
assigns[:questions] = @questions
end
it "should render the 'survey/question_for_candidate' partial" do
args = {:partial => 'question_for_candidate', :locals => {:question =>
an_instance_of(Question)}}
template.should_receive(:render).with(args).exactly(@questions.nitems
).times
render 'survey/show'
end
end
c) not use any fixtures in the view specs but instead use mocks for
that: it's faster and you can check exactly what needs to happen instead
of relying on what happens to be in the fixture.
As you can see mocks are now all over the place. No fixtures were used ;)
Thanks a lot,
Caio
On Nov 11, 2007 6:01 AM, Hans de Graaff <[EMAIL PROTECTED]> wrote:
> You are trying to test a lot of things at the same time, which is one of
> the reasons that it is now hard to diagnose a problem.
>
> I would tackle this by
> a) writing a separate spec for the partial _question_for_candidate
> b) write a separate spec for the helper that renders the question
> b) in the view spec for /survey/show use should_receive to determine
> that the helper is actually being called
> c) not use any fixtures in the view specs but instead use mocks for
> that: it's faster and you can check exactly what needs to happen instead
> of relying on what happens to be in the fixture.
>
> I'm afraid that I don't see immediately why your current setup won't
> work, but untangling things along the lines sketched above should
> hopefully get you to a situation where it becomes easier to see what
> happens.
>
> > before(:each) do
> > assigns[:configurations] = {:survey_name => 'Whatever'}
> > assigns[:questions] = Array.new
> > assigns[:questions][4] = questions(:faixa_etaria)
>
> I am a little bit suspicious about this construction, though. I'm not
> sure whether assigns is a normal Array in this case, so I'd create the
> Array and populate it before handing it to assigns:
>
> @questions = Array.new
> @questions[4] = ...
> assigns[:questions] = @questions
>
> Kind regards,
>
> Hans
>
> _______________________________________________
> rspec-users mailing list
> [email protected]
> http://rubyforge.org/mailman/listinfo/rspec-users
>
--
Caio Moritz Ronchi
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users