Bazley
Bazley

Reputation: 2847

Rails unit test assert_template failure

I have the following test: test/integration/authentication_test.rb:

require 'test_helper'

class AuthenticationTest < ActionDispatch::IntegrationTest

  def setup
    @admin = users(:barry) # grab user from fixtures
  end

  test "trying to view a user before logging in" do
    get user_path(@admin)
    assert_template 'sessions/new'
    assert_not flash.empty?
    assert_select "div#error_explanation"
    assert_select "div.field_with_errors"
    assert_select "a[href=?]", logout_path, count: 0
    assert_not is_logged_in?
  end
end

The test fails with the following error:

FAIL["test_trying_to_view_a_user_before_logging_in", AuthenticationTest, 2.206536] test_trying_to_view_a_user_before_logging_in#AuthenticationTest (2.21s)
    expecting <"sessions/new"> but rendering with <[]>
    test/integration/authentication_test.rb:11:in `block in <class:AuthenticationTest>'

Relevant bits of the users_controller.rb:

class UsersController < ApplicationController

  before_action :logged_in_user, only: [:index, :show, :edit, :update, :destroy]

  def show
    @user = User.find_by_callsign(params[:callsign])
    @page_name = "user_page"
    redirect_to root_url and return unless @user.activated
  end
  .
  .
end

sessions_helper.rb:

def logged_in_user
  unless logged_in?
    store_location
    flash[:danger] = "Please log in."
    redirect_to login_url
  end
end

def logged_in?
  !current_user.nil?
end

In routes.rb:

get 'login', to: 'sessions#new'

I don't understand why the test is failing. When I perform the steps manually it all works. Is there a known issue with assert_template? When I comment out assert_template 'sessions/new' in the test, it passes.

EDIT:

In log/test.log: it is indeed redirecting to the correct template (Redirected to http://www.example.com/dominos/newname). But it doesn't have any 'rendered' lines. The last few lines of the failed test are:

Redirected to http://www.example.com/dominos/newname
Completed 302 Found in 21ms (ActiveRecord: 2.5ms)
  [1m[35m (0.4ms)[0m  SELECT COUNT(*) FROM "personas"
  [1m[36m (0.2ms)[0m  [1mROLLBACK[0m

In the test.log file for successful tests involving assert_template, there are various 'Rendered' lines following a redirect, for example:

Rendered personas/new.html.erb within layouts/application (2.0ms)

Is this perhaps part of why the test is failing? Why does the page not render?

Upvotes: 1

Views: 1450

Answers (4)

Terrytreks
Terrytreks

Reputation: 266

I used follow_redirect! to force the test to redirect. Then I could check that it redirected to the correct page with assert_template.

Upvotes: 1

leevigilstroy
leevigilstroy

Reputation: 604

I'm clearly late to the party, but SaulGoodman. I'm stuck with a very similar problem, so your post is useful. I'm finding that the assert_template method doesn't work if there is a redirect involved. It's only solid if a page is being 'rendered'. I think. Perhaps I'm wrong but that's the lesson I'm slowly picking up on. Hope you fixed this one up.

Upvotes: 0

bridiver
bridiver

Reputation: 1714

Another fix would be to use assert_redirected_to

Upvotes: 3

dpassage
dpassage

Reputation: 5453

In an integration test like this, the get statement doesn't follow redirects. To follow the redirect, use get_via_redirect. More information is here.

Upvotes: 4

Related Questions