Why does my UserMailer in dev mode not output Rails.logger.info? - ruby-on-rails

I need to debug using Rails.logger.info in my user_mailer.rb
Any idea why the Rails.logger.info is not outputting in the user_mailer but it does everywhere else?
Thanks

According to this, it should work just fine within a Mailer.
To write in the current log use the logger.(debug|info|warn|error|fatal) method from within a controller, model or mailer
You could always just debug using a puts statement instead and check the logs for the output.
puts "I am inside the Mailer method"

Related

Rails 6 & deliver_later doesn't affect ActionMailer::Base.deliveries

After upgrading to Rails 6 I am noticing that default mailer's .deliver_later is not working the same as in Rails 5.
Configuration:
config.active_job.queue_adapter = :inline
When running Mailer.register_email(...).deliver_later - nothing is stored in ActionMailer::Base.deliveries. This array gets filled if I run perform_enqueued_jobs - it seams like queue_adapter = :inline doesn't work the way I expect it to work.
If I run Mailer.send(...).deliver_now then ActionMailer::Base.deliveries has proper value in it.
Any idea why this is happening and how to solve this?
I had same problem in my tests. A search on the Internet yielded nothing, so I started experimenting.
I tried wrapping the call method of sending mail in
assert_emails 1 do
Mailer.register_email(...).deliver_later
end
After that, ActionMailer::Base.deliveries populated correctly.
If the exact number of emails could easily change, this is another option:
assert_changes 'enqueued_jobs.size' do
# Some code that sends email with deliver_later
end
This allows you to test that emails were sent but it disregards the exact number (which is a limitation of the asserts_emails method - other than this, the asserts_emails method is great).
I found that the enqueued_jobs method is very helpful in testing anything background jobs, including deliver_later
NOTE: the above example only checks that the enqueued jobs list was changed. If you want to be more specific and check that the queue was changed with emails, you should do this:
assert_changes 'enqueued_jobs.select {|job| job["job_class"] == "ActionMailer::MailDeliveryJob"}.size' do
# Some code that sends email with deliver_later
end
The issue
The issue lies in two new lines of code added to Rails 6 (line 1 & line 2),
where basically, the callback before_setup defined here (in RSpec) and here (in Minitest) gets overridden (by this), thus forcing the queue_adapter to be the test adapter instead of the one defined by config.active_job.queue_adapter.
Workaround
So in order to use the queue_adapter defined by config.active_job.queue_adapter and therefore restore the Rails 5 behaviour we can do something like the below.
# spec/support/active_job/test_helper.rb
module ActiveJob
module TestHelper
def before_setup
super
end
end
end

How to check if the log has a certain message when a method from the helper spec is called?

I am new to Rspec.
I am trying to test whether I get a required message in the test.log file when i try to run a helper method in helper_spec.rb.
I have searched a lot but only found how to check a message printing using stdout.
Generally, it should be enough to check whether the logger has been called which can be accomplished with
expect(Rails.logger).to receive(:level).with("your log message")
(substitute :level with the level you're calling the logger with).

Rails puts to console

In my Rails app, there are some cases where code is being outputted with the puts command (for debugging purposes). Is there anyway to follow this output in the rails console (with the rails c command)? Or is there any other way to debug/view logs in the rails console?
Thanks!
For debugging, use Rails.logger instead of puts. For example:
Rails.logger.info "Some debugging info"
This will be logged to a log file in rails_app_root/log directory. If you are running in development environment locally, it will be logged to rails_app/log/development.log file.
Now, to see the log as they come in you can use tail command, like this:
tail -f log/development.log
Hope it helps.
Rails.logger is the best solution,one more think i want to add,if you want separate log file you could use like this
def read(args)
unless args.blank?
cache_key= self.get_cache_key(args)
end
logger = Logger.new("#{Rails.root}/log/cache_read.log")
logger.error("cache read scope == #{cache_key.to_s}")
end
so cache_read.log file having only this method log only.

Sending emails in test mode with ActionMailer in rails 3

I am having a slightly odd problem with sending mail in test mode with Rails 3
It seems that my mailers are not returning anything. For example I have a mailer called UserMailer. Users can make changes that require approval in the app so this has a method called changes_approved that should send the user an email notifying them that their changes have been approved.class
UserMailer < ActionMailer::Base
default :from => "from#example.com"
def changes_approved(user, page)
#user = user
#page = page
mail(:to => user.email, :subject => "Your changes have been approved")
end
end
In my controller I have the following line
UserMailer.changes_approved(#page_revision.created_by, #page_revision.page).deliver
However my tests fail at this point with the error:
undefined method `deliver' for nil:NilClass
When I trigger the same actions on the development site tho (http://localhost:3000 through a browser), the emails are sent out correctly and everything works quite happily
And to add further confusion, I am using devise for authentication and the emails for that seem to be working correctly both in test and development modes. Certainly I am not getting this same error and according to my email-spec tests, everythings working
So this leads me to believe that I have a problem with my mailers rather than my test mail config per se but I have no idea what. Any suggestions would be much appreciated
Thanks
I used https://gist.github.com/1031144
to convert
# Rails 2 method:
UserMailer.should_receive(:deliver_signup)
to
# Cumbersome Rails 3 method:
mailer = mock
mailer.should_receive(:deliver)
UserMailer.should_receive(:signup).and_return(mailer)
I had a similar problem - probably the UserMailer.changes_approved method is being replaced with a mock method, which returns nil (I wasn't using shoulda for that test, but that's my best guess).
My code looked like this (modified to use your example):
UserMailer.expects(:changes_approved).once
I fixed it with an additional stub:
#mailer = stub(:deliver)
UserMailer.expects(:changes_approved).once.returns(#mailer)
The nil is now replaced with #mailer.
To test the delayed action mailer we need to first change the configuration of delayed_job (in config/initializers/delayed_job_config.rb) to
Delayed::Worker.delay_jobs = !Rails.env.test?
and in your tests the expectation should be set to
mock_mail = mock(:mail)
mock_mail.should_receive(:deliver)
UserMailer.should_receive(:changes_approved).with(user, page).and_return(mock_mail)
Well I have found the answer,
it looks like the problem was in the way I was testing these mailers. In each of the controller tests I had a line similar to
UserMailer.should_receive(:changes_approved).with(user, page)
Whilst this test was passing fine, it appeared to break the mailer itself. I have removed this line from the tests and now they pass ok. Subsequent tests against ActionMailer::Base.deliveries.last to check the details of the sent email are correct appear to be ok so I am happy that this line is not neccessary.
If anyone has an explanation as to why this breaks tho, I would be interested to find out
Thanks anyways

Quickly debug helper methods in script\console

How would I quickly debug helper methods in script\console. I'm talking about making changes and then debugging, over and over again.
This is a lot easier with Model methods, since all I have to do is use
reload!
to test the updated code, whereas to test a helper method, I have to do something like this
foo = ActionView::Base.new
foo.extend YourHelperModule
each time to I want to test a change.
What does reload! do? and can I modify it to add the above lines of code?
I don't think you can do that without hacking Rails. However, there's a workaround - debugging helper method in rails debugger:
1) gem install ruby-debug
2) ruby script/server --debugger
3) place <% debugger %> into some view and open that page in browser
4) server window "turns into" console, where you can debug helper methods
5) 'return' command ends the debugging
If you modify the helper method and run the debugger again, you will get recent version of the method.
More info about debugger is here: http://railscasts.com/episodes/54-debugging-with-ruby-debug
I would suggest not using script console and writing tests in either Test::Unit or rspec instead. Google should get you pointed in the right direction there is a ton of information out there.
If you're doing something "again and again" then you should be automating it. Assuming you know what your helper function should do then as mentioned elsewhere you should be able to write a test (or tests) for it.
Here's a sample that tests application_helper. It lives in my test/unit directory:
require 'test_helper'
class ApplicationHelperTest < ActiveSupport::TestCase
include ApplicationHelper
test "number_as_pct shows 2dp as default" do
assert_equal "1.10%", number_as_pct(0.011)
end
test "number_as_pct shows more dp when required" do
assert_equal "1.1000%", number_as_pct(0.011, :precision => 4)
end
end

Resources