Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock not working on module function

I have written the function send_formatted_email which formats email subject and message then calls the send_email function in a separate module.

Now I have to test that send_formatted_email is calling send_email with the expected arguments. For this purpose I am trying to mock send_email using patch, but it is not getting mocked.

test.py

@patch('app.util.send_email')
def test_send_formatted_email(self, mock_send_email):
    mock_send_email.return_value = True
    response = send_formatted_email(self.comment, to_email)
    mock_send_email.call_args_list
    ....

views.py

def send_formatted_email(comment, to_email):
    ...
    message = comment.comment
    subject = 'Comment posted'
    from_email = comment.user.email
    ...
    return send_email(subject, message, to_email, from_email)

util.py

def send_email(subject, message, to, from):
    return requests.post(
        ...
    )

I even tried app.util.send_email = MagicMock(return_value=True) but this didn't work either. Any idea what I am doing wrong?

like image 467
Afnan Nazir Avatar asked Aug 14 '16 12:08

Afnan Nazir


People also ask

How do you mock a function in a module Jest?

There are two ways to mock functions: Either by creating a mock function to use in test code, or writing a manual mock to override a module dependency.

How do you mock a node module?

Mocking Node modules​ If the module you are mocking is a Node module (e.g.: lodash ), the mock should be placed in the __mocks__ directory adjacent to node_modules (unless you configured roots to point to a folder other than the project root) and will be automatically mocked. There's no need to explicitly call jest.

How do you mock only one function from a module in Jest?

Spying on the function using jest. import * as moduleApi from '@module/api'; // Somewhere in your test case or test suite jest. spyOn(moduleApi, 'functionToMock'). mockReturnValue({ someObjectProperty: 42 }); Usage wise it's basically the same as manually mocking it as described in the previous section.


1 Answers

Like jonrsharpe already mentioned there is already an answer under another question.

In my case I were not able to use one of the alternatives that are provided (reload or patching my own module).

But I now just importing the needed method right before usage:

def send_formatted_email(comment, to_email):
    ...
    message = comment.comment
    subject = 'Comment posted'
    from_email = comment.user.email
    ...
    from app.util import send_email
    return send_email(subject, message, to_email, from_email)

This will load the module method after you patched it.

Cons:

  • The import is executed before each method call.
like image 126
Eruvanos Avatar answered Oct 21 '22 00:10

Eruvanos