Python : 通过引用传递给 C 库的参数的模拟 return 值

Python : Mocked return value of parameter passed by reference to a C library

我有一个 C 库,我正在为其编写包装器。这个库中的大多数函数都采用 'an out arguments' (结果在传递的变量中返回)。 那么在以下情况下如何测试案例: - self._system 作为 None 返回(来自 C 作为副作用),但是 - 函数 returns 成功

详情请看下方代码

main.py

myLibDLL = CDLL('mylib.dll')

class System():
    _system = None

    def __init__(self):
        self._system = c_void_p(None)

    def GetSys(self):
        # - The C function prototype 
        #       ERROR_CODE XXX_API CGetSys(void* phSys)
        # - myLibDLL.CGetSys() is the call to mock
        retErr = myLibDLL.CGetSys(byref(self._system))
        checkReturnErr(retErr)

        if self._system.value == None:
            raise BaseException('Failed to Get Sys') # case to test

单元测试文件

@patch("main.myLibDLL.CGetSys")
def test_GetSys_sysIsNone_afterCGetSysisCalled(self, mock_CGetSys):
    self.sys = System()

    # What expectations shoudl I set here?
    mock_CGetSys.return_value = 0 # to pass checkReturnErr()        
    mock_CGetSys.??? = None # the question 

    # test
    with self.assertRaises(BaseException):
        self.system.GetSys()
  • 创建一个与 C 函数具有相同签名的函数。
  • 将该函数分配给模拟的 side_effect。

    def nullifyCSysPtr(cSysPtr):
        # assigne None to c_void_p type
        cSysPtr._obj.value = None
    
    @patch("main.myLibDLL.CGetSys")
    def test_GetSys_sysIsNone_afterCGetSysisCalled(self, mock_CGetSys):
        # moking
        mock_CGetSys.return_value = 0 # to pass checkReturnErr()        
        mock_CGetSys.side_effects = nullifyCSysPtr # the answer
    
        # test
        with self.assertRaises(BaseException):
            self.sys = System()
            self.system.GetSys()