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

时间:2018-10-09 17:05:03

标签: python mocking ctypes

我有一个C库,正在为其编写包装。该库中的大多数函数都带有“输出参数”(结果将在传递的变量中返回)。 因此,在以下情况下如何测试情况:  -self._system返回为None(从C作为副作用),但是  -函数返回成功

更多信息,请参见下面的代码

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()

1 个答案:

答案 0 :(得分:0)

  • 创建一个与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()