Lawrence Sproul Lawrence Sproul - 7 months ago 81
Ruby Question

rails 5 assert_select fails in test, because sort order is different between model and test

Rails5 – testing problem - i am developing a web app in rails 5 beta3.
I want to test if a link is produced on the page. The link does show on the development site when I run 'rails s', but the test fails. So i put byebug to see where it goes wrong. UPDATE: I found that the user controller is sending users sorted by 'id DESC' but the test is using default sort so it matches the first try by accident, then fails on the second.

I cannot get the test to run with anything other than default sort due to errors. adding related code from model and controller.

'Rake test' passes on first user, but fails on second user.


FAIL ["test_index_including_pagination", UsersIndexTest, 202.31457826300175]
test_index_including_pagination#UsersIndexTest (202.31s)
Expected at least 1 element matching "a[href="/users/205739844"]", found 0..
Expected 0 to be >= 1.
test/integration/users_index_test.rb:16:in 'block (2 levels) in '
test/integration/users_index_test.rb:14:in `block in '


When I try to use code from controller index action I get error. Demonstrated with byebug output:

(byebug) User.search(term: "al", page: 1 )
*** ArgumentError Exception: wrong number of arguments (given 1, expected 2)
nil


GEMFILE:

source 'https://rubygems.org'

gem 'rails', '5.0.0.beta3'
ruby "2.3.0"
gem 'puma', '~> 3.4.0'
gem 'pg', '~> 0.18.4'
gem 'sass-rails', '~> 6.0.0.beta1'
gem 'uglifier', '~> 3.0.0'
gem 'coffee-rails', '~> 4.1.1'
gem 'therubyracer', '~> 0.12.2'
gem 'jquery-rails', '~> 4.1.1'
gem 'turbolinks', '~> 5.0.0.beta2'
gem 'jbuilder', '~> 2.4.1'
gem 'sdoc', '~> 0.4.1', group: :doc
gem 'argon2', '~> 1.0.0'
gem 'bootstrap-sass', '~> 3.3.6'
gem 'sprockets-rails', '~> 3.0.4'
gem 'will_paginate', '~> 3.1.0'
gem 'bootstrap-will_paginate', '~> 0.0.10'
gem 'faker', '~> 1.6.3'
group :development, :test do
gem 'byebug', '~> 8.2.4'
end
group :development do
gem 'web-console', '~> 3.1.1'
gem 'listen', '~> 3.0.6'
gem 'spring', '~> 1.7.1'
end
group :test do
gem 'rails-controller-testing', '~> 0.1.1'
gem 'minitest', '~> 5.8.4'
gem 'minitest-rails', :github => 'blowmage/minitest-rails', :branch => 'rails5'
gem 'minitest-reporters', '~> 1.1.8'
end
group :production do
gem 'rails_12factor', '~> 0.0.3'
end


TESTCODE:

test "index including pagination" do
log_in_as(@user)
get users_path
assert_template 'users/index'
assert_select 'div.pagination'
User.paginate(page: 2).each do |user|
byebug
assert_select 'a[href=?]', user_path(user)
end
end


CONTROLLER:

def index
@users = User.search(params[:term], params[:page])
end


MODEL:

def self.search(term, current_page)
if term
page(current_page).where('name LIKE ?', "%#{term}%").order('id DESC')
else
page(current_page).order('id DESC')
end
end

def self.search(term, page)
if term
where('lower(name) LIKE ?', "%#{term}%".downcase).paginate(page: page, per_page: 5).order('id DESC')
else
paginate(page: page, per_page: 5).order('id DESC')
end
end

Answer

OK, the test was not passing the hashed values properly to the model.

The original test code below provided the wrong set of users to the test so I got a failure:

User.paginate(page: 2).each do |user|

Adding sort to the test as follows produced a strange error indicating that only one value was passed then two were expected. The code I used was:

User.search((term: 'al', page: 1).each do |user|

Fixed the problem by changing test code to:

User.search('al', 1).each do |user|

The test now passes without errors. It seems that writing the test with hashes (term: 'al', page: 1) caused the error.