【问题标题】:magic_mock_db.connect.assert_called() fails even though it's calledmagic_mock_db.connect.assert_called() 失败,即使它被调用
【发布时间】:2021-06-14 16:39:22
【问题描述】:

我正在使用 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()方法并成功连接,但断言失败。

我做错了什么?

提前致谢。

【问题讨论】:

  • 不应该是mock_db().connect.assert_called()吗?你在实例上调用它,而不是在类上。相关:stackoverflow.com/q/38199008/3001761.
  • @jonrsharpe 对不起,你能解释一下吗?因为当我注释掉mock_db.connect.assert_called() 并离开mock_db.assert_called_once() 它通过了。
  • 完全正确 - mock_db 被调用一次,返回实例 connect 被调用。您正在测试的代码不包含 peewee.MySQLDatabase.connect - 在 返回值 上调用 connect
  • @jonrsharpe 所以我必须将其测试为mock_db().connect.assert_called?当我这样做时,它会返回TypeError: missing a required argument: 'database'。这是否意味着我必须将self.freezer 传递给mock_db() 作为参数?即mock_db(database=self.freezer)
  • mock_db.return_value.connect...

标签: python-3.x python-unittest peewee python-unittest.mock vscode-python


【解决方案1】:

根据jonrsharpe,我在模拟类mock_db 上调用connect,而不是应该返回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()

【讨论】:

  • 你不应该在mock_db.return_value.connect = mock_db.connect() 周围跳舞——事实上这会导致一个问题,mock_db.connect 被调用是因为你刚刚调用了它。您应该删除该行并在调用 open_freezer 方法后执行 mock_db.return_value.connect.assert_called()
猜你喜欢
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
相关资源
最近更新 更多