djangomockingpytestpython-unittestpytest-django

Mocking does not work as expected (Django)


I have this code:

// app1.service.py


database = {
    1: "Alice",
    2: "Bob",
    3: "Charlie"
}


def get_user_from_db(user_id):
    return database.get(user_id)

// app1.tests.test_service.py

import pytest
from unittest import mock

from app1.service import get_user_from_db


@mock.patch("app1.service.get_user_from_db")
def test_get_user_from_db(mock_get_user_from_db):
    mock_get_user_from_db.return_value = "Mocked Alice"
    username = get_user_from_db(1)  # If I change it to mock_get_user_from_db(1) everything works fine
    assert username == "Mocked Alice"

When i run 'pytest' in the command line, I get this:

E       AssertionError: assert 'Alice' == 'Mocked Alice'
E         - Mocked Alice
E         + Alice

In the tutorial I am watching, get_user_from_db(1) returns "Mocked Alice", but in my local machine it returns just "Alice". It works fine when I use

username = mock_get_user_from_db(1)

instead of the

username = get_user_from_db(1)

Question: It this the expected behaviour that username = get_user_from*db(1) returns "Alice" in my case? (in the youtube video it returns "Mocked Alice") or am I just doing something wrong?


Solution

  • You should import it after mocking, otherwise it still refers to the old non-mocked item:

    from unittest import mock
    
    import pytest
    
    
    @mock.patch("app1.service.get_user_from_db")
    def test_get_user_from_db(mock_get_user_from_db):
        mock_get_user_from_db.return_value = 'Mocked Alice'
    
        from app1.service import get_user_from_db
    
        username = get_user_from_db(
            1
        )  # If I change it to mock_get_user_from_db(1) everything works fine
        assert username == "Mocked Alice"

    The mocking tool can not change the behavior of the original object, so basically, it replaces it by a function that acts differently.