Erik Pukinskis
2008-May-06 20:03 UTC
[rspec-users] Can you use RSpec to test initializers?
Hi there! I''m trying to spec out some code that will set the smtp_settings in a custom ActiveMailer object. Basically I want to check that if my configuration object has the right smtp_server, that the ActiveMailer object gets set up correctly. So, my spec looks like this: it "uses smtp server if config says so" do GitoriousConfig.should_receive(:[]).with(''smtp_settings'').and_return({ :address => "smtp.postoffice.net", }) Mailer.smtp_settings[:address].should == "smtp.postoffice.net" end The trouble is, the code that sets the mailer settings is in an initializer (config/initializers/mailer.rb) and it gets run long before my spec gets run, and so it never encounters my mock. Is there any way I can get the initializer code to run inside my spec? I know I could create a separate initialize method on my Mailer object that has the initialization stuff, and call that method from both my test and my initializer, but that seems less ideal than just calling the initializer from the spec. Any advice? I can''t find any information at all online about using Rspec with initializers. Thank you! Erik
On May 6, 2008, at 4:03 PM, Erik Pukinskis wrote:> Hi there! > > I''m trying to spec out some code that will set the smtp_settings in a > custom ActiveMailer object. Basically I want to check that if my > configuration object has the right smtp_server, that the ActiveMailer > object gets set up correctly. So, my spec looks like this: > > it "uses smtp server if config says so" do > GitoriousConfig.should_receive(: > []).with(''smtp_settings'').and_return({ > :address => "smtp.postoffice.net", > }) > > Mailer.smtp_settings[:address].should == "smtp.postoffice.net" > end > > The trouble is, the code that sets the mailer settings is in an > initializer (config/initializers/mailer.rb) and it gets run long > before my spec gets run, and so it never encounters my mock. Is there > any way I can get the initializer code to run inside my spec? > > I know I could create a separate initialize method on my Mailer object > that has the initialization stuff, and call that method from both my > test and my initializer, but that seems less ideal than just calling > the initializer from the spec. > > Any advice? I can''t find any information at all online about using > Rspec with initializers.You could try using Kernel#load to load the file inside the spec, but you might get strange errors on the other side... Let me know how it works out. Scott
On Tue, May 6, 2008 at 4:03 PM, Erik Pukinskis <erik at snowedin.net> wrote:> Hi there! > > I''m trying to spec out some code that will set the smtp_settings in a > custom ActiveMailer object. Basically I want to check that if my > configuration object has the right smtp_server, that the ActiveMailer > object gets set up correctly. So, my spec looks like this: > > it "uses smtp server if config says so" do > GitoriousConfig.should_receive(:[]).with(''smtp_settings'').and_return({ > :address => "smtp.postoffice.net", > }) > > Mailer.smtp_settings[:address].should == "smtp.postoffice.net" > end > > The trouble is, the code that sets the mailer settings is in an > initializer (config/initializers/mailer.rb) and it gets run long > before my spec gets run, and so it never encounters my mock. Is there > any way I can get the initializer code to run inside my spec?> > I know I could create a separate initialize method on my Mailer object > that has the initialization stuff, and call that method from both my > test and my initializer, but that seems less ideal than just calling > the initializer from the spec. > > Any advice? I can''t find any information at all online about using > Rspec with initializers. >Erik, I would not test configuration settings this way. Setting up mock expectations helps when you are talking to another object whose implementation you don''t have yet, or don''t want the test to rely. Since you are testing configuration settings I would vote that you test against the actual configuration settings. A quick sidebar, I don''t like setting up SMTP settings in an initializer. I prefer to do it in the correct environment/*.rb file. This is because you often don''t want your development or test environments sending out emails (at least not via the same route as production). If you do move the configuration setup from your initializer to an environment file then what you want to test is going to be more difficult since it may be different for each environment. And when you run a spec it''s going to be executed in the test environment, which is probably not the SMTP settings you wanted to ensure got setup. You are probably wanting to make sure the production environment runs with specific settings. In the past I''ve foregone automated testing of my configuration settings. I usually setup my production.rb configuration on the production server, and then every time I deploy I''m symlink that file into RAILS_ROOT/config/environment/. This greatly reduces the risk that the production settings is going to be modified or altered unintentionally. Keeping snapshot backups of your production setup (or even just the configuration files) also helps reduce risk even more. You could put your production files in their own svn or git repository so you can easily revert back when you do make changes to those files. If you really want to test the production settings you could right a test which loaded up the rails application in the production environment, printed out the SMTP settings in YAML, and then your test could read that in using YAML.load and you could ensure the settings are what you expect. IE: settings = YAML.load( `RAILS_ENV=production ruby -r config/environment.rb -e "y ActionMailer::Base.smtp_settings"` ) settings[:domain].should == "smtp.example.com" -- Zach Dennis http://www.continuousthinking.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080507/6730ce38/attachment.html>