修补在SUT中导入和实例化的模块

时间:2014-03-31 20:53:29

标签: python unit-testing mocking python-import

我正在尝试在导入其他两个模块的类上运行单元测试,而我正在尝试使用mock修补这些模块。其中一个模块在我正在测试的类中实例化,我无法修补它。看来我已经设法修补了另一个。

在此代码中修补sequence.processor模块的最佳方法是什么?

目录结构

logger.py
parser/
    __init__.py
    docparser.py
sequence/
    __init__.py
    processor.py
tests/
    testdocparser.py

/parser/docparser.py

import logger
from sequence.processor import Processor

class DocParser(object):
    def __init__(self, reader_writer):
        self.processor = Processor(reader_writer)

    def write_and_parse(self, products):
        logger.log(products)
        self.processor.process(products)

/tests/testdocparser.py

import unittest
from mock import MagicMock, patch

from parser import docparser

class DocParserTests(unittest.TestCase):
    def setUp(self):
        self.mock_writer = MagicMock()
        self.docparser = docparser.DocParser(self.mock_writer)

    @patch("parser.docparser.logger") # This seems to be patched properly
    @patch("parser.docparser.Processor") # This is not patched
    def test_write_and_parse(self, mock_logger, mock_proc):
        products = "products"
        self.docparser.write_and_parse(products)

1 个答案:

答案 0 :(得分:1)

您在Processor中修补了test_write_and_parse(),但它已在DocParser.__init__()中实例化,该setUp()来自class DocParserTests(unittest.TestCase): def setUp(self): self.mock_writer = MagicMock() with patch('parser.docparser.Processor'): self.docparser = docparser.DocParser(self.mock_writer) @patch("parser.docparser.logger") def test_write_and_parse(self, mock_logger): products = "products" self.docparser.write_and_parse(products)

这应该可行,但我还没有测试过:

setUp()

我使用了上下文管理器而不是装饰器来避免更改@patch("parser.docparser.logger") # This seems to be patched properly @patch("parser.docparser.Processor") # This is not patched def test_write_and_parse(self, mock_proc, mock_logger): # ... 签名(添加参数)。

此外,test_write_and_parse()的模拟参数的顺序在您的代码中是不正确的。以下摘自mock docs

  

当您嵌套修补程序装饰器时,模拟将按照它们应用的相同顺序传递给修饰函数(应用装饰器的正常python顺序)。这意味着自下而上......

正确的顺序:

mock_proc

对于cource来说,在您的特定情况下并不重要,因为以后不会使用mock_logger和{{1}}。