即使被调用,magic_mock_db.connect.assert_call() 也会失败

问题描述

我使用 vscode-python 的扩展和 python 的 unittest 来测试 peewee 是否成功连接到数据库。 这是正在测试的类:

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')

调用open_freezer() 将连接到数据库并打印出 CONNECTED。 这是测试套件:

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()

在最后一行,又名 mock_db.connect.assert_called() 失败并显示以下 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)

如您所见,它打印出 CONNECTED 从而表明它已调用 connect() 方法并成功连接,但断言失败。

我做错了什么?

提前致谢。

解决方法

根据 jonrsharpe,我在模拟类 connect 上调用 mock_db,而不是它应该返回到 self.freezer 的内容。正确的做法是:

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()