Python内部实体模拟



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

所以对象是在内部创建的,并且在方法退出后它不能从外部访问。

使用python 2.7

在foobar.py

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

我想测试是否配置。

据我所知,补丁装饰器是为此制作的,但不幸的是,测试用例接收的MagicMock对象与内部创建的MagicMock对象不同,并且我无法接近方法内部的对象。

我试过了:

class TestFooBar(TestCase):
    def setUp(self):
         self.myfoobar = FooBar()
    @mock.patch('foobar.ConfigParser')
    def test_read(self,mock_foobar):
        self.myfoobar.method("configuration.ini")
        assert mock_foobar.called # THIS IS OKAY
        assert mock_foobar.read.called # THIS FAILS
        mock_foobar.read.assert_called_with("configuration.ini") # FAILS TOO

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

当然,一种方法是重构并给.read()或init()一个ConfigReader对象,但是更改代码并不总是可能的,我想掌握方法的内部对象而不触及被测试的模块。

你很接近了!问题是,您正在模拟类,但随后您的测试检查是否在该模拟类上调用了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")

相关内容

  • 没有找到相关文章

最新更新