Search code examples
python-3.xpython-unittestpeeweepython-unittest.mockvscode-python

magic_mock_db.connect.assert_called() fails even though it's called


I am using vscode-python's extension with python's unittest to test if peewee successfully connects to the database. This is the class that is being tested:

import logging
from datetime import (datetime, timezone)

# 3rd party libraries
import peewee


log_fmt = "%(asctime)s - %(funcName)s - %(name)s - %(levelname)s - %(message)s"
# enable logging
logging.basicConfig(
    format=log_fmt,
    level=logging.INFO
)

logger = logging.getLogger(__name__)


class Freezer():

    db_name = "db"
    db_username = "db_user"
    db_pswd = "db_pswd"

    def __init__(self):
        self.freezer = peewee.MySQLDatabase(
            database=Freezer.db_name,
            user=Freezer.db_username,
            password=Freezer.db_pswd,
            host="localhost",
            port=3306
        )

    def open_freezer(self):
        if self.freezer.connect():
            print('CONNECTED')

when called open_freezer() will connect to the database and print out CONNECTED. and this is the test suite:

import unittest
from unittest.mock import (MagicMock, patch)

from src.freezer import (Freezer, BaseModel, PlatiniumBotUser, peewee)


class FreezerTestSuites(unittest.TestCase):

    def test_open_freezer(self):
        with patch("src.freezer.peewee.MySQLDatabase", autospec=True) as mock_db:
            self.freezer = Freezer()
            mock_db.assert_called_once()
            self.freezer.open_freezer()
            mock_db.connect.assert_called()

in the last line, aka mock_db.connect.assert_called() fails with the below AssertionError:

test_open_freezer (test_freezer.FreezerTestSuites) ... 
CONNECTED
FAIL
NoneType: None

======================================================================
FAIL: test_open_freezer (test_freezer.FreezerTestSuites)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/gadd/vscodeworkspace/db_testing/tests/test_freezer.py", line 23, in test_open_freezer
    mock_db.connect.assert_called()
  File "/usr/lib/python3.8/unittest/mock.py", line 882, in assert_called
    raise AssertionError(msg)
AssertionError: Expected 'connect' to have been called.

----------------------------------------------------------------------
Ran 1 test in 0.117s

FAILED (failures=1)

As you can clearly see it prints out CONNECTED thus indicating that it has called the connect() method and successfully connected, but the assertion fails.

What am I doing wrong?

thanks in advance.


Solution

  • Per jonrsharpe, I was calling connect on the mocked class mock_db instead of what it was supposed to return to the self.freezer. The correct way to do it is:

    def test_open_freezer(self):
         with patch("peewee.MySQLDatabase", autospec=True) as mock_db:
              self.freezer = Freezer()
              mock_db.assert_called()
              self.freezer.open_freezer()
              mock_db.return_value.connect.assert_called()