Reputation: 4272
Basically what is happening is when I'm doing the integration testing in my rspec specifications I'm testing the reset password functionality, and I'm using a third party api call to send out the email. I want to trust the third party api to send out the email and ignore the response entirely.
Here is the code that I'm using right now, but it is still sending out the email as well as failing because the call to send_password_reset (which is where the third party api call is contained) is "not" being called according to Mocha
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
I don't think posting the factories used to create this will reveal anything else, but you think that would help you help me I'll do it.
I have also tried to change the Cilent.expects to @client.expects and I still have the same issue. I'm not tied to the Mocha framework since this is actually my first mock I've ever done.
I've also read that I'm not supposed to be mocking objects in integration testing, but I don't know of a way to not send out the email when the test is called.
Just thought that I should add the controller action in there as well in case I should be changing something in there...
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
Im receiving this error when I run the test
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)>'
SOLUTION
Using the code below from @Veraticus and moving it to the top of the spec solved the issue.
Upvotes: 2
Views: 902
Reputation: 16084
The problem is that you're not calling the send_password_reset
method on the class; you're calling it on an instance of that class. Use this:
Client.any_instance.expects(:send_password_reset).returns(true)
The client
found by Client.find_by_email
will have the expectation set up on it correctly.
Upvotes: 3