Starting my journey on TDD with Rspec and having some issues.
Can’t understand why my rspec fails on if … OR condition.
def director
@movie = Movie.find_by_id(params[:id])
if @movie.nil? or @movie.director.empty?
flash[:notice] = "The movie has no director info"
redirect_to movies_path
else
# success
end
end
Rspec test:
before ... #stubs
it 'assigns movies array in director action' do
Movie.stub(:find_by_id).and_return(@movie)
get "director", :id => 1
...
end
Error:
1) MoviesController assigns movies array in director action
Failure/Error: get "director", :id => 1
NoMethodError:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.empty?
If record is not found, then @movie.nil? should satisfy the condition and @movie.director.empty? shouldn’t evaluated against; is that correct?
In this case I don’t care if there’s no such record or the director field of requested record is blank, I treat it the same way.
Appreciate your help.
UPDATE
I’ve removed some controller stuff into model like this:
controller:
def director
@movies = Movie.same_director_by_id(params[:id])
if @movies.blank?
redirect_to movies_path
end
end
movie:
def self.same_director_by_id (id)
movie = self.find_by_id(id)
if movie.nil? or movie.director.blank?
return []
else
return self.where("id != ?", id).find_all_by_director(movie.director)
end
end
rspec:
it 'assigns movies array in director action' do
Movie.should_receive(:same_director_by_id).and_return([@movie])
get "director", :id => 1
assigns(:movies).should be_kind_of(Array)
end
Now all controller specs pass beautifully.
I’ll test model separately.
UPDATE 2:
The issue was that I stubbed :director on a Model, not on a mock!
apneadiving was correct.
As discussed in comments, it’s mandatory to mock/stub every object/method.
directorywas missing here.