config.action_mailer.delivery_method = :test
Compare to the line in config/environments/development.rb
config.action_mailer.delivery_method = :smtp
Setting this to test stops e-mails being sent, and instead they are sent to an array, ActionMailer::Base.deliveries. This array is reset before each test, by the way.
Here is a simple mailer to test.
class Notifier < ActionMailer::Base
default :from => "DB@mysite.com"
add_template_helper(ApplicationHelper)
# Sets up an e-mail for notifying the user to activate his account.
def signup_notification user
@name = user.username
@login = user.login
@url = "http://mysite.com/activate/#{user.activation_code}"
mail :to => user.email, :subject => 'Activate your account'
end
def page_error(err, request)
@err = err
@request = request
mail :to => 'admin@mysite.com', :subject => 'Page error'
end
end
In your controller, you might invoke the first like this:
Notifier.signup_notification(@user).deliver
In the test, you will need to break that up, so you can examine the mail object.
class NotifierTest < ActionMailer::TestCase
test "signup_notification" do
# Create a mock user
user = TestUser.new 'tester', 'tester@nowhere.com'
# Invoke the mailer method
mail = Notifier.signup_notification user
# Deliver the mail
mail.deliver
# Check the mail got sent
assert !ActionMailer::Base.deliveries.empty?
# Check it is the right mail
assert_equal 'Activate your account', mail.subject
assert_equal ["tester@nowhere.com"], mail.to
assert_equal ["DB@mysite.com"], mail.from
assert_match "Visit this url to activate your account",
mail.body.encoded
end
end
Here is the TestUser definition.
class TestUser
attr_reader :username, :email, :login
def initialize username, email
@username = username
@email = email
@login = username.gsub ' ', ''
end
def activation_code; "abcd"; end
end
The second method in the mailer above is for sending error reports to the administrator. Here is a method that generates an error, and sends that to the mailer:
test "page_error" do
request = TestRequest.new
begin
raise "A test error"
rescue Exception => err
mail = Notifier.page_error(err, request)
mail.deliver
assert !ActionMailer::Base.deliveries.empty?
assert_equal "Page error", mail.subject
assert_equal ["admin@mysite.com"], mail.to
assert_equal ["DB@mysite.com"], mail.from
assert_match "error encountered!", mail.body.encoded
end
end
Here is the TestRequest definition; it simply returns the string "good" if the method name is recognised - that is enough for the mailer to wok with, and will still highlight any mistyped or made-up method names.
class TestRequest
# Returns the string "good" if the method is recognised
def method_missing method, *args
return "good" if [:fullpath, :request_method, :query_parameters,
:request_parameters, :referer].include? method
super
end
end
end
No comments:
Post a Comment