I'm working my way through the Hartl Ruby on Rails Tutorial (4th Edition) and I've come across a problem with some tests I'm trying to run - specifically the exercise in section 11.2.3. All of my tests are green up to this point.
I test the new piece of code:
vagrant@ubuntu-18:/vagrant/sample_app/test$ rails test:mailers
Started with run options --seed 59483
1/1: [======================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.33304s
1 tests, 9 assertions, 0 failures, 0 errors, 0 skips
Everything is groovy.
I attempt to run the full test suite:
vagrant@ubuntu-18:/vagrant/sample_app/test$ rails test
Running via Spring preloader in process 11914
Started with run options --seed 56533
ERROR["test_account_activation", UserMailerTest, 1.2505091589991935]
test_account_activation#UserMailerTest (1.25s)
ActionView::Template::Error: ActionView::Template::Error: undefined method `merge' for nil:NilClass
app/views/user_mailer/account_activation.html.erb:6:in `_app_views_user_mailer_account_activation_html_erb__2910351700178259135_47130470135880'
app/mailers/user_mailer.rb:10:in `account_activation'
test/mailers/user_mailer_test.rb:9:in `block in <class:UserMailerTest>'
48/48: [========================================================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.71036s
48 tests, 206 assertions, 0 failures, 1 errors, 0 skips
Bugger. Testing which I won't bother reproducing here confirms that it's definitely the same piece of code that's failing in one place and working in the other.
However, if instead of calling rails test
I call rails test:run
, then this happens:
vagrant@ubuntu-18:/vagrant/sample_app/test$ rails test:run
Started with run options --seed 50303
48/48: [========================================================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.72194s
48 tests, 215 assertions, 0 failures, 0 errors, 0 skips
And similarly, if I use rake test
or rake test:run
, then everything is fine.
vagrant@ubuntu-18:/vagrant/sample_app/test$ rake test
(in /vagrant/sample_app)
Started with run options --seed 9429
48/48: [========================================================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.70475s
48 tests, 215 assertions, 0 failures, 0 errors, 0 skips
vagrant@ubuntu-18:/vagrant/sample_app/test$ rake test:run
(in /vagrant/sample_app)
Started with run options --seed 50280
48/48: [========================================================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.73529s
48 tests, 215 assertions, 0 failures, 0 errors, 0 skips
Can anyone explain what's going on here? And ideally how to make just a rails test
call work again?
EDIT
Started rails test
with the same seed used by rails test:run
to show that it's not anything to do with test ordering.
vagrant@ubuntu-18:/vagrant/sample_app/test$ rails test:run
Started with run options --seed 326
48/48: [=======================================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.66690s
48 tests, 215 assertions, 0 failures, 0 errors, 0 skips
vagrant@ubuntu-18:/vagrant/sample_app/test$ rails test --seed 326
Running via Spring preloader in process 28117
Started with run options --seed 326
ERROR["test_account_activation", UserMailerTest, 1.605607868055813]
test_account_activation#UserMailerTest (1.61s)
ActionView::Template::Error: ActionView::Template::Error: undefined method `merge' for nil:NilClass
app/views/user_mailer/account_activation.html.erb:6:in `_app_views_user_mailer_account_activation_html_erb__2910351700178259135_47130458820540'
app/mailers/user_mailer.rb:10:in `account_activation'
test/mailers/user_mailer_test.rb:9:in `block in <class:UserMailerTest>'
48/48: [=======================================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.64637s
48 tests, 206 assertions, 0 failures, 1 errors, 0 skips
rake TESTOPTS="--seed=326"
also succeeds.
EDIT 2
Test:
require 'test_helper'
class UserMailerTest < ActionMailer::TestCase
test "account_activation" do
user = users(:michael)
user.activation_token = User.new_token
mail = UserMailer.account_activation(user)
assert_equal "Account Activation", mail.subject
assert_equal [user.email], mail.to
assert_equal ['noreply@example.com'], mail.from
assert_match user.name, mail.body.encoded
assert_match user.activation_token, mail.body.encoded
assert_match CGI.escape(user.email), mail.body.encoded
end
end
Method Tested: (where the line beginning mail to: is user_mailer.rb:10)
class UserMailer < ApplicationMailer
def account_activation(user)
@user = user
mail to: @user.email, subject: "Account Activation"
end
end
Fixture:
michael:
name: Michael Example
email: michael@example.com
password_digest: <%= User.digest('password') %>
admin: true
activated: true
activated_at: <%= Time.zone.now %>
Template:
<h1>Sample App</h1>
<p>Hi <%= @user.name %>, </p>
<p>Welcome to the Sample App! Please click on the link belowe to activate your account.</p>
<%= link_to "Activate", edit_account_activation_url(@user.activation_token, email: @user.email) %>
Thanks to @AJFaraday for pointing out in the comments that the Spring preloader was running.
I called spring stop
, and the problem resolved itself.
Spring seems to have turned itself back on again, but rails test
is now giving the same test results as the other three methods.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.