lundi 24 août 2015

Rails integration test failing for nil object in partial after following redirection

My application has three models: Interviewer, Candidate, Interview.

A Candidate "has many" interviews, and an Interview "belongs to" a candidate. This means that each interview has a reference to a candidate.

My routes.rb has:

resources :interviewers
resources :candidates
resources :interviews

and I am using these fixtures:

# interviewers.yml
foobar:
  name: Foo Bar
  email: foo.bar@example.com

# candidates.yml
some_candidate:
  name: Some
  surname: Candidate
  email: some.candidate@example.com

# interviews.yml
some_interview:
  datetime: 2015-02-11 11:02:57
  candidate_id: some_candidate

Interviewers have to log in, so I initially wrote an integration test to verify that, after login, they were redirected to their profile page:

def setup
  @interviewer = interviewers(:foobar)
end

test "login with valid information redirects to interviewer page" do
  get login_path
  post login_path, session: { email: @interviewer.email, password: 'password' }
  assert is_logged_in?
  assert_redirected_to @interviewer
  follow_redirect!
  assert_template 'interviewers/show'
  assert_select "a[href=?]", interviewer_path(@interviewer)

However I now want to change this behaviour, so that interviewers are redirected to the list of interviews. Such list is created by the Interview controller:

def index
  @interviews = Interview.paginate(page: params[:page])
end

and each interview is rendered using a partial:

<li id="interview-<%= interview.id %>">
  <span class="datetime">
    [<%= link_to interview.datetime.to_s(), interview %>]
  </span>
  <span class="candidate">
    <%= link_to interview.candidate.name + " " + interview.candidate.surname, interview.candidate %>
  </span>
</li>

This is how I modified the integration test:

def setup
  @interviewer = interviewers(:foobar)
  @candidate = candidates(:some_candidate)
end

test "login with valid information redirects to interview list" do
  get login_path
  post login_path, session: { email: @interviewer.email, password: 'password' }
  assert is_logged_in?
  assert_redirected_to interviews_path
  follow_redirect!
  assert_template 'interviews/index'
  assert_select "a[href=?]", candidate_path(@candidate)

However this test fails with the error:

ActionView::Template::Error: ActionView::Template::Error: undefined method `name' for nil:NilClass

which originates from interview.candidate.name of the partial.

How should I fix my test (or fixture) so that the candidate in the partial is not nil?

Thank you.

Aucun commentaire:

Enregistrer un commentaire