2015-04-12 71 views
2

我试图测试设计是否发送确认电子邮件。这对我来说是一种挑战,因为测试在Rails中使用了不同的环境,我不确定我是否正确地选择了正确的路线。 这是我的rspec测试。如何使用devise,rspec,capybara和mailspec测试设计邮件传递

describe "Sign up:", :type => :feature do 

    before(:each) do 
    @user = FactoryGirl.build(:user) 

    visit root_path 

    click_link "Sign Up" 

    fill_in "Name", :with => @user.name 
    fill_in "Email", :with => @user.email 
    fill_in "Password", :with => @user.password 
    fill_in "Password confirmation", :with => @user.password 

    click_button "Sign up" 
end 

describe "user gets a confirmation email" do 
subject { ActionMailer::Base.deliveries.last } 
it { is_expected.to deliver_to(@user.email) } 
end 

这是我运行规范时的消息。

Failure/Error: it { is_expected.to deliver_to(@user.email) } 
NoMethodError: 
    undefined method `perform_deliveries' for nil:NilClass 

我想测试此功能,但Rails可以在测试环境中发送电子邮件吗?如果是这样的代码通过什么样的代码?我已经为sendgrid设置了邮件程序,所以我也可以显示它。用户的设计被设置为可确认的,所以确认电子邮件应该出来。

+0

问题可能是您的邮件程序异步交付,交付实际上是在您的期望之后执行的。即一个'睡眠1',然后你的期望可能会解决你的问题(虽然这被广泛地认为是反模式) –

回答

1

你可以尝试在测试环境中写:

config.action_mailer.perform_deliveries = true 

我希望它会帮助你!

2

确保你在你有这个集config/environments/test.rb有这一套:

config.action_mailer.delivery_method = :test 

在你的天赋,你也可以只测试ActionMailer::Base.deliveries已经改变:

describe "Sign up:", :type => :feature do 
    # ... 

    it "sends a confirmation email" do 
    expect { 
     click_button "Sign up" 

     # for example. the point is to wait for the AJAX response 
     page.find('p.thanks', text: 'Thanks for signing up') 
    }.to change { ActionMailer::Base.deliveries.size }.by(1) 
    end 
end 

同样,如果你正在使用Sidekiq,你可以检查Sidekiq工作的数量是否增加。个人而言,我会节省测试电子邮件的细节以进行单元测试,并使用功能测试确保将所有内容连接在一起。

此外,如果您想手动验证电子邮件正在发送,Mailcatcher是相当不错的。

相关问题