尝试在 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
嘲笑者上调用方法 frob
、create_connection
和 do_something
...
我发现了问题:
mocker = MagicMock(name="my_mock_dll")
行用一个新的 mocker 替换了 mocker,它并没有真正修补到实际的 class,我得到了垃圾输出。
问题
我正在为 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
嘲笑者上调用方法 frob
、create_connection
和 do_something
...
我发现了问题:
mocker = MagicMock(name="my_mock_dll")
行用一个新的 mocker 替换了 mocker,它并没有真正修补到实际的 class,我得到了垃圾输出。