Python内部实体嘲笑

时间:2015-08-26 17:28:08

标签: python unit-testing mocking patch magicmock

我想测试一个方法,无论它是否调用临时内部对象的特定方法。 (ConfigParser.read)

因此,对象在内部创建,并且在方法退出后无法从外部访问。

使用python 2.7

在foobar.py

domain.com/image/image.php

我想测试是否调用了config.read。

据我所知,修补程序装饰器是为此而制作的,但不幸的是,测试用例收到的MagicMock对象与内部创建的对象不同,而且我无法靠近方法内部的对象。 / p>

我试过这样:

 import ConfigParser

 class FooBar:
     def method(self, filename):
         config=ConfigParser.ConfigParser()
         config.read(filename)
         do_some_stuff()

问题是:   - 在self.myfoobar.method内部创建ConfigReader之前创建mock_foobar。   - 调试时,mock_foobar有关于之前调用的内部数据,但没有" read" property(用于模拟读取方法的内部MagicMock)

当然,一种方法是重构并给.read()或 init ()一个ConfigReader对象,但是并不总是可以更改代码,而且我&# 39; d。在不接触待测模块的情况下,掌握方法的内部对象。

1 个答案:

答案 0 :(得分:3)

你真是太近了!问题是你正在嘲笑这个类,但是你的测试检查是在那个mock类上调用了read() - 但实际上你希望在调用类时返回的实例上调用read()。以下工作 - 我发现第二个测试比第一个测试更具可读性,但它们都有效:

import ConfigParser
from unittest import TestCase

from mock import create_autospec, patch, Mock 


class FooBar(object):
    def method(self, filename):
        config=ConfigParser.ConfigParser()
        config.read(filename)


class TestFooBar(TestCase):

    def setUp(self):
         self.myfoobar = FooBar()

    @patch('ConfigParser.ConfigParser')
    def test_method(self, config_parser_class_mock):
        config_parser_mock = config_parser_class_mock.return_value

        self.myfoobar.method("configuration.ini")

        config_parser_class_mock.assert_called_once_with()
        config_parser_mock.read.assert_called_once_with("configuration.ini")

    def test_method_better(self):
        config_parser_mock = create_autospec(ConfigParser.ConfigParser, instance=True)
        config_parser_class_mock = Mock(return_value=config_parser_mock)

        with patch('ConfigParser.ConfigParser', config_parser_class_mock):
            self.myfoobar.method("configuration.ini")

        config_parser_class_mock.assert_called_once_with()
        config_parser_mock.read.assert_called_once_with("configuration.ini")