如何为Python的__del__函数编写单元测试用例

3

我已经设置了以下代码,并且我有一个测试用例来测试Db.__init__,那么我该如何测试__del__呢?你能提供一个例子吗?

import psycopg2


class Db(object):
    def __init__(self):
        import app
        conn_string = "host='{}' port='{}' dbname='{}' user='{}' password='{}'".format(app.app.config['DB_HOST'], \
                      app.app.config['DB_PORT'], app.app.config['DB_NAME'], app.app.config['DB_USER'], \
                      app.app.config['DB_PASSWORD'])
        self.conn = psycopg2.connect(conn_string)

    def __del__(self):
        self.conn.close()

测试用例

@ddt
class TestDB(unittest.TestCase):
    @patch('psycopg2.connect')
    def test_db_constructor(self, mock_psycopg2_connect):
        mock_psycopg2_connect.returned_value = True
        db = Db()

        self.assertTrue(db.conn)

您打错了,应该是 mock_psycopg2_connect.return_value - Martijn Pieters
你不应该使用 __del__(参见这个答案)。或许你可以用 with 语句 来解决问题。 - Solomon Slow
1个回答

2

直接调用该方法,通过__init__方法模拟出self.conn

@patch('psycopg2.connect')
def test_db_destructor(self, mock_psycopg2_connect):
    db = Db()
    mock_conn = mock_psycopg2_connect.return_value
    close = mock_conn.close

    db.__del__()
    close.assert_called_once()

你原来的测试有一个缺陷;你拼错了 return_value,所以你的模拟连接从来没有返回过 True;它只返回了一个新的模拟对象。那个模拟对象刚好有一个真值:

>>> from unittest.mock import MagicMock
>>> mock = MagicMock()
>>> mock.connect()
<MagicMock name='mock.connect()' id='4536051752'>
>>> bool(mock.connect())
True

为了正确测试connect()方法的返回值是否存储在db.conn中,请测试该属性是否与模拟返回的对象完全相同:

@patch('psycopg2.connect')
def test_db_constructor(self, mock_psycopg2_connect):
    mock_conn = mock_psycopg2_connect.return_value

    db = Db()
    self.assertTrue(db.conn is mock_conn)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接