需要从lxml.etree模块中模拟ElementTree类的write()方法

时间:2019-01-13 20:42:34

标签: python unit-testing mocking lxml cython

我正在编写一个方法,该方法使用来自lxml.etree的ElementTree类的write方法。在编写测试时,我想对此进行模拟,以便单元测试不会在驱动器中写很多东西。

文件中的代码看起来像这样

    # myapp\gla.py
    from lxml.etree import Element, ElementTree

    def my_func(element):
        root = Element(element)
        xml = ElementTree(root)
        xml.write('path_to_file')

测试如下:

    # tests\test_gla.py
    from unittest import patch
    from myapp.gla import my_func

    @patch('myapp.gla.ElementTree.write')
    def test_my_func(self, mock_write):
        my_func('rootElement')
        mock_write.assert_called_once()

我明白了

    Traceback (most recent call last):
      File "C:\Anaconda2\envs\py36\lib\unittest\mock.py", line 1171, in patched
        arg = patching.__enter__()
      File "C:\Anaconda2\envs\py36\lib\unittest\mock.py", line 1243, in __enter__
        original, local = self.get_original()
      File "C:\Anaconda2\envs\py36\lib\unittest\mock.py", line 1217, in get_original
        "%s does not have the attribute %r" % (target, name)
    AttributeError: <cyfunction ElementTree at 0x000001FFB4430BC8> does not have the attribute 'write'

2 个答案:

答案 0 :(得分:0)

ElementTree is a function, not a type。它返回_ElementTree类型的对象,它是that that has the function write

我还没有对此进行测试(我对模拟不了解/足够了解),但是我怀疑

 @patch('myapp.gla._ElementTree.write')

应该可以工作(尽管您可能还需要自己导入_ElementTree)。

答案 1 :(得分:0)

找到了我自己的问题的答案。

像这样重新编写测试:

# tests\test_gla.py
from unittest import patch, MagicMock
from myapp.gla import my_func

@patch('myapp.gla.ElementTree')
def test_my_func(self, mock_write):
    mock_write().write = MagicMock()
    my_func('rootElement')
    mock_write().write.assert_called_once()