'Python: How to use mock or patch to check that a method inside another method has run?

I've read through a whole bunch of answers, but still don't understand where I need to mock and/or which class/module to patch and keep getting module does not have the attribute errors.

I have a View class which contains a method I'd like to test. That method does not return anything. What it does is: checks an if/else statement based on the method's parameter, and in both cases fires off another method (imported from another module) with different args. I want to see if that inner method is being called with the correct arguments.

Here's the simplified code:

from django.views import View
from django.conf import settings
from my_project import email

class ProcessSub(View):
    def handle_ineligible(ineligible_dict):
        if ineligible_dict["status"] == "NOT_FOUND":
            email.send_email(settings.NOT_FOUND_EMAIL_ID)
        else:
            email.send_email(settings.INELIGIBLE_EMAIL_ID)

What I want to do in my test is call handle_ineligible with a known status and check whether email.send_email was called with the right EMAIL_ID.


What I've tried:

@mock.patch('myproject.services.email.send_email')
    def test_not_found(self, mock_email_send):
    INELIGIBLE_DICT = {'status': 'NOT_FOUND'}
    view = ProcessSub()
    view.handle_ineligible(INELIGIBLE_DICT)
    mock_email_send.assert_called_with(settings.INELIGIBLE_EMAIL_ID)

This fails with the following AssertionError:

E           AssertionError: expected call not found.
E           Expected: send_email('asdf')
E           Actual: not called.


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source