I need some help with this. I have installed email-spec (courtesy of BMabey) and I have configure things thusly: Scenario: E-Mail Exchange Rates to notify parties Given a currency exchange feed from the Bank of Canada When the currency exchange retrieval script runs Then I should receive an email Then /should receive (an|\d+) e-?mails?/ do |amount| amount = 1 if amount == "an" unread_emails_for(current_email_address).size.should == amount.to_i end ../environments/test.rb # Tell ActionMailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test config.gem ''bmabey-email_spec'', :lib => ''email_spec'' class MailerPublic < ActionMailer::Base def forex_daily_notice(address,rates) rates_effective = Date.today.to_s(:db) recipients address.to_a from "ForexService at harte-lyne.ca" reply_to "support at harte-lyne.ca" subject "#{rates_effective} - Foreign Exchange Rates Notice" body :rates_effective => rates_effective, :rates => rates end end ./views/mailer_public/forex_daily_notice.text.plain.erb Canada Customs foreign currency exchange rates for currency conversion of shipments made on <%=@rates_effective%> When I run this ./bin/script.rb ... # Format and email the results. if fx_hash_array puts "got an array" send_to = ''test_email at example.com'' MailerPublic.deliver_forex_daily_notice!(send_to,fx_hash_array) puts ActionMailer::Base.deliveries.length ActionMailer::Base.deliveries.each { |m| puts m } end Then I see this: got an array 0 This is my first attempt at using ActionMailer so no doubt I have overlooked something basic. Can anyone tell me what it is? -- Posted via http://www.ruby-forum.com/.
James Byrne wrote:> I need some help with this. I have installed email-spec (courtesy of > BMabey) and I have configure things thusly: > > Scenario: E-Mail Exchange Rates to notify parties > Given a currency exchange feed from the Bank of Canada > When the currency exchange retrieval script runs > Then I should receive an email > > Then /should receive (an|\d+) e-?mails?/ do |amount| > amount = 1 if amount == "an" > unread_emails_for(current_email_address).size.should == amount.to_i > end > > > ../environments/test.rb > # Tell ActionMailer not to deliver emails to the real world. > # The :test delivery method accumulates sent emails in the > # ActionMailer::Base.deliveries array. > config.action_mailer.delivery_method = :test > config.gem ''bmabey-email_spec'', :lib => ''email_spec'' > > > class MailerPublic < ActionMailer::Base > def forex_daily_notice(address,rates) > rates_effective = Date.today.to_s(:db) > recipients address.to_a > from "ForexService at harte-lyne.ca" > reply_to "support at harte-lyne.ca" > subject "#{rates_effective} - Foreign Exchange Rates Notice" > body :rates_effective => rates_effective, :rates => rates > end > end > > > ./views/mailer_public/forex_daily_notice.text.plain.erb > Canada Customs foreign currency exchange rates for > currency conversion of shipments made on <%=@rates_effective%> > > When I run this > > ./bin/script.rb > ... > # Format and email the results. > if fx_hash_array > puts "got an array" > send_to = ''test_email at example.com'' > MailerPublic.deliver_forex_daily_notice!(send_to,fx_hash_array) > puts ActionMailer::Base.deliveries.length > ActionMailer::Base.deliveries.each { |m| puts m } > end > > Then I see this: > > got an array > 0 > > This is my first attempt at using ActionMailer so no doubt I have > overlooked something basic. Can anyone tell me what it is? >Looks right to me. To be honest though I have not used ActionMailer outside of Rails (where it just works out of the box). I don''t see anything wrong with the approach you are taking. Maybe the rails mailing list could provide better advice. Sorry, I couldn''t be of any help. -Ben
Ben Mabey wrote:> Sorry, I couldn''t be of any help. >Actually, you were a great help, but on a different thread. The reason I was not seeing anything is that the default environment is "development" and I have things configured so that the deliveries array is only used in "test". Adding "puts" in front of the call to %x() in the step definition file showed that the email is generated as expected. I have something else wrong with my test, probably the address that I am checking for, -- Posted via http://www.ruby-forum.com/.
I have reached this point in testing using email-spec: The code: # Format and email the results. if fx_hash_array send_to = ''email at example.com'' MailerPublic.deliver_forex_daily_notice!(send_to,fx_hash_array) ActionMailer::Base.deliveries.each { |m| puts m } unless Rails.env.production? end The Feature Scenario: Scenario: E-Mail Exchange Rates to notify parties Given a currency exchange feed from the Bank of Canada And an empty email queue When the currency exchange retrieval script runs Then I should receive an email The Steps: Then /currency exchange retrieval script runs/ do stdout = %x(#{RAILS_ROOT}/bin/hll_forex_ca_feed.rb #{@xchg_source}) puts stdout puts current_email_address end ... local_email_steps Then /should receive (an|\d+) e-?mails?/ do |amount| amount = 1 if amount == "an" unread_emails_for(current_email_address).size.should == amount.to_i end The output: Scenario: E-Mail Exchange Rates to notify parties # features/app/models/currency_exchange_rates/ currency_exchange_rates.feature:19 xml source is: /home/byrnejb/Software/Development/Projects/proforma.git/doc/data/fx-noon-all-2009-04-15.xml Given a currency exchange feed from the Bank of Canada # features/app/models/currency_exchange_rates/step_definitions/ currency_exchange_rates_steps.rb:5 And an empty email queue # features/step_definitions/local_email_steps.rb:28 From: ForexService at harte-lyne.ca Reply-To: support at harte-lyne.ca To: email at example.com Subject: [ForEx] 2009-04-28 - Foreign Exchange Rates Notice Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=mimepart_49f713ebd7061_2d4d155c1a4737c82cd --mimepart_49f713ebd7061_2d4d155c1a4737c82cd Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: Quoted-printable Content-Disposition: inline Canada Customs foreign currency exchange rates for 2009-04-28: --mimepart_49f713ebd7061_2d4d155c1a4737c82cd-- email at example.com When the currency exchange retrieval script runs # features/app/models/currency_exchange_rates/step_definitions/ currency_exchange_rates_steps.rb:11 Then I should receive an email # features/step_definitions/local_email_steps.rb:49 expected: 1, got: 0 (using ==) Diff: @@ -1,2 +1,2 @@ -1 +0 (Spec::Expectations::ExpectationNotMetError) ./features/step_definitions/local_email_steps.rb:51:in `/should receive (an|\d+) e-?mails?/'' features/app/models/currency_exchange_rates/currency_exchange_rates.feature:23:in `Then I should receive an email'' The email To: header value and the current_email_address are the same insofar as I can tell. But the email_spec matcher is not finding that address in the deliveries array. Any ideas as to what I am missing? -- Posted via http://www.ruby-forum.com/.
James Byrne wrote:> I have reached this point in testing using email-spec:...> The email To: header value and the current_email_address are the same > insofar as I can tell. But the email_spec matcher is not finding that > address in the deliveries array. Any ideas as to what I am missing?I have determined what the problem is. I just do not know how to fix it. What is happening is that I am testing a standalone (outside of a Rails instance) Ruby script that requires ActionMailer. I call this script from inside the step definition using the %x alias for Kernel#`. When this runs it picks up the test environment and directs email output into ActionMailer::Base.deliveries. However, this array only exists during the script''s existence and naturally disappears when he script terminates. In consequence, the results are not available for testing. I have, up to now, simply accepted the magic of injecting test methods into classes and using the results. Now I need to have explained how I get this to magic work with stand alone scripts. How do I get ActionMailer::Base.deliveries created by ActionMailer in the script to remain available to cucumber/email-spec? -- Posted via http://www.ruby-forum.com/.
James Byrne wrote:> James Byrne wrote: > >> I have reached this point in testing using email-spec: >> > ... > >> The email To: header value and the current_email_address are the same >> insofar as I can tell. But the email_spec matcher is not finding that >> address in the deliveries array. Any ideas as to what I am missing? >> > > I have determined what the problem is. I just do not know how to fix it. > > What is happening is that I am testing a standalone (outside of a Rails > instance) Ruby script that requires ActionMailer. I call this script > from inside the step definition using the %x alias for Kernel#`. When > this runs it picks up the test environment and directs email output into > ActionMailer::Base.deliveries. However, this array only exists during > the script''s existence and naturally disappears when he script > terminates. In consequence, the results are not available for testing. > > I have, up to now, simply accepted the magic of injecting test methods > into classes and using the results. Now I need to have explained how I > get this to magic work with stand alone scripts. How do I get > ActionMailer::Base.deliveries created by ActionMailer in the script to > remain available to cucumber/email-spec? >I have plans to make email-spec work with any SMTP mailer and thereby making it more "black-box"y and allow for external processes to be easily tested... However, that is not done yet. As it stands now you have two options: a) have the test execution and script in the same process or b) Use ARMailer[1] in your testing environment. ARMailer places the messages in a database for queuing. So instead of checking the in-memory array EmailSpec will check the queue on the database. Since this is just for testing then you could use a lightweight sqlite3 db to store this. -Ben 1. http://github.com/seattlerb/ar_mailer/tree/master
On Apr 29, 10:37?am, Ben Mabey <b... at benmabey.com> wrote:> However, that is not done yet. ?As it stands now you > have two options: a) have the test execution and script in the same > process or b) Use ARMailer[1] in your testing environment. ?ARMailer > places the messages in a database for queuing. ?So instead of checking > the in-memory array EmailSpec will check the queue on the database. ? > Since this is just for testing then you could use a lightweight sqlite3 > db to store this.For what it''s worth, I believe that ARMailer requires you to change your base class for mailers from ActionMailer::Base to ActionMailer::ARMailer, which makes it difficult to use ARMailer only in your test environment. However, the adzap-ar_mailer[1] fork supports using the ActionMailer::Base base class, which makes it easy to use ARMailer only for testing (by specifying it in config/ environments/test.rb) while using another delivery mechanism for development/production. 1. http://github.com/adzap/ar_mailer/tree/master
What I ended up doing is dumping the deliveries array to a file from the standalone script and reading it into the deliveries array inside the step definitions file. A kludge, but it suffices. -- Posted via http://www.ruby-forum.com/.