基本上发生的事情是,当我在我的 rspec 规范中进行集成测试时,我正在测试重置密码功能,并且我正在使用第三方 api 调用来发送电子邮件。我想信任第三方 api 发送电子邮件并完全忽略响应。
这是我现在正在使用的代码,但它仍在发送电子邮件并且失败,因为根据 Mocha 对 send_password_reset 的调用(其中包含第三方 api 调用)是“不”被调用的
before(:each) do
@client = Factory(:user_with_clients).clients.first
end
it 'should send out the email(mock) set a temporary password and take them back to the login page' do
# WHEN THE MOCK WAS MOVED HERE THE SPEC PASSSED
visit '/client_portal/reset_password/new'
fill_in 'email', with: @client.email
click_button 'Send password reset'
# THIS NEEDED TO BE MOVED TO THE TOP OF THE FUNCTION
Client.expects(:send_password_reset).returns(true)
current_path.should eq('/client_portal/login')
page.should have_content('Check your email')
@client.reload
@client.tmp_password.should_not eq(nil)
end
我不认为发布用于创建这个的工厂会揭示任何其他内容,但你认为这会帮助你帮助我,我会做的。
我也尝试将 Cilent.expects 更改为 @client.expects,但我仍然遇到同样的问题。我不依赖于 Mocha 框架,因为这实际上是我做过的第一个模拟。
我还读到我不应该在集成测试中模拟对象,但我不知道在调用测试时不发送电子邮件的方法。
只是想我应该在那里添加控制器动作,以防我应该在那里改变一些东西......
def create
client = Client.find_by_email(params[:email])
if client
client.set_tmp_password
if client.send_password_reset
redirect_to '/client_portal/login', notice: 'Check your email for the password reset link'
else
redirect_to '/client_portal/login', notice: 'There was an error resetting your password. Please try one more time, and contact support if it doesn\'t work'
end
else
flash.now[:notice] = 'No account with that email address was found'
render :new
end
end
我在运行测试时收到此错误
1) Reset a users password user is not logged in valid email address supplied should send out the email(mock) set a temporary password and take them back to the login page
Failure/Error: Client.any_instance.expects(:send_password_reset).returns(true)
Mocha::ExpectationError:
not all expectations were satisfied
unsatisfied expectations:
- expected exactly once, not yet invoked: #<AnyInstance:Client(id: integer, first_name: string, last_name: string, email: string, password_digest: string, signup_charge: decimal, monthly_charge: decimal, active: boolean, created_at: datetime, updated_at: datetime, monthly_charge_day: integer, sold_by_user_id: integer, tmp_password: string)>.send_password_reset(any_parameters)
# ./spec/requests/client_portal/reset_password_spec.rb:14:in `block (4 levels) in <top (required)>'
解决方案
使用来自@Veraticus 的以下代码并将其移至规范的顶部解决了该问题。