尝试在 python 包装单元测试中模拟 DLL

Trying to mock a DLL in a python wrapper unittest

问题

我正在为 python 中的 DLL 编写包装器,因为它变得越来越复杂我想要一些简单的单元测试来检查传递给 dll 的参数是否格式正确以及一些错误检查我有工作。由于 DLL 通过网络连接到外部资源,没有它就无法工作,测试它可能很麻烦,我想模拟它。

这是一个小例子,它的行为就像我的包装器一样:

from ctypes import c_void_p, c_int, c_char_p, WinDLL, byref

class prod:

    def do_something(self, some_string: str, some_int: int):
        self.my_dll.do_something(
            self.handle,
            c_char_p(some_string.encode("utf-8")),
            c_int(some_int),
        )

    def __init__(self, dll_path: str = "dll_name.dll"):
        self.my_dll = WinDLL(dll_path)
        a = self.my_dll.frob()
        print(a)
        # prepare handle creation
        create_handle = self.my_dll.create_connection
        create_handle.restype = c_void_p
        # actually create a connection handle
        self.handle = create_handle()

我试过的

阅读文档后,我决定使用 MagicMock 来修补对 WinDLL 的调用,这样我就可以用模拟程序替换包装器中的 my_dll。我创建的一个小示例测试类似于 https://docs.python.org/3/library/unittest.mock-examples.html#mocking-classes:

import logging
import unittest
from unittest.mock import patch, MagicMock, Mock

from prod import prod

class TestInit(unittest.TestCase):
    @patch("prod.WinDLL")
    def test_init(self, mocker):
        mocker = MagicMock(name="my_mock_dll")
        instance = mocker.return_value
        instance.frob.return_value="asdf"
        pr = prod("./some/path")
        pr.do_something("asdf", 6)
        print(mocker.mock_calls)
        print(instance.mock_calls)

我现在希望调用 self.my_dll.frob() 到 return "asdf",但是现在 returns <MagicMock name='WinDLL().frob()' id='46863080'>,看起来有些东西没有实例化对吗?

此外,mock_calls 都打印空列表,这也是我没想到的。我希望在 instance 嘲笑者上调用方法 frobcreate_connectiondo_something...

我发现了问题:

mocker = MagicMock(name="my_mock_dll") 行用一个新的 mocker 替换了 mocker,它并没有真正修补到实际的 class,我得到了垃圾输出。