I am uncertain about the way of including several modules into RSpec, so let me describe my situation.
Under app/helpers
I have two files with helpers, containing the modules ApplicationHelper
and MailersHelper
. Although these are view helpers, which I use in my views and mails, I also use some of their methods in my tests, so they must by accessible within a describe
clause.
Under app/spec/mailers
I also have a file, containing the module Helpers
. This module contains methods, that are only to be used in the tests (mostly wrapper methods for long expectations).
Additionally I have the following code:
class Helpers
include Singleton
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::NumberHelper
end
def helper
Helper.instance
end
It serves the purpose of making view helpers available in tests. Currently this code resides within the Helper
module right before the wrapper methods, as they use the Helper.instance
method.
I have three mailers, that I want to test. So how do I make all those things accessible in the tests?
Use include directly under describe in each of the mailer specs like so:
require 'spec_helper'
describe MyMailer do
include ApplicationHelper
include MailersHelper
include Helpers
...
end
In the file helpers.rb
I do this:
require 'spec_helper'
module Helpers
include MailersHelper
include ApplicationHelper
...
end
RSpec.configure { |c| c.include Helpers }
and in each mailer spec I use require_relative './helpers'
Like above but instead of including ApplicationHelper
and MailersHelper
in Helpers
, I do this:
RSpec.configure do |c|
c.include Helpers
c.include ApplicationHelper
c.include MailersHelper
end
What I am so confused about is:
I do the RSpec.configure part in a separate file (helpers.rb
), which I require_relative
in my mailers specs. So this means these modules will be available only to my mailers specs, not to the whole suit, right? (As it would have been the case if I had done this in spec_helper.rb).
What is the best practice of organizing methods, which are not view helpers, but are helpers shared between several classes (mostly Controllers or Mailers). How should they be named, where should they be put?
Constant autoloading is really a hard topic for me - sometimes you get a module/class directly available and you don't need to do anything (but this might depend on the exact naming of your file/module), sometimes you must require
it or relative_require
it, but you must be careful where exactly you do this, because otherwise it will become globally available, and sometimes you have a special way of including things like with RSpec.configure... oh, boy!
This should be done in spec_helper.rb
. You can conditionally include
modules depending on the spec type.
RSpec.configure do |config|
config.include MailersHelper, type: :mailer
end
Any spec in spec/mailers
will now automatically include MailersHelper
.
You can trigger this manually by doing
RSpec.describe FooConstant, type: :mailer do
# ... etc
end
in cases where the spec doesn't reside in spec/mailers
but you want to treat it like one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With