When should I use `autospec=True` with the mock library?
当使用
一方面,本文警告我们始终使用
... you should always use the
create_autospec method and theautospec parameter with the@patch and@patch.object decorators.
另一方面,
所以我的问题是:我什么时候应该使用
我担心不使用
我可以理解建议强制使用
也许下面的内容可以帮助您更清楚地了解Autospec的优点和缺点。
简而言之,使用autospec可以确保模拟中使用的属性实际上是模拟类的一部分。
因此,通过下面的示例,我将说明当技术上您可能不希望测试通过时,测试将如何通过:
举个简单的例子,我们将测试:
1 2 3 4 5 6 7 8 | class Foo: def __init__(self, x): self.x = x class Bar: def __init__(self): self.y = 4 self.c = Foo('potato') |
测试代码:
1 2 3 4 5 6 7 8 | class TestAutoSpec(unittest.TestCase): @patch('some_module.Foo') def test_autospec(self, mock_foo_class): mock_foo_obj = mock_foo_class.return_value bar_obj = some_module.Bar() self.assertTrue(hasattr(bar_obj.c, 'you_should_fail')) |
现在,如果回顾
这是因为如果一个属性不存在于
1 | <class 'unittest.mock.MagicMock'> |
这肯定会使
现在,要为此编写一个成功的测试并仍然使用autospec=true,只需根据需要在模拟测试中创建属性。请记住,之所以需要这样做,是因为autospec无法了解动态创建的属性,即在创建实例时在
因此,autospec的方法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class TestAutoSpec(unittest.TestCase): @patch('some_module.Foo', autospec=True) def test_autospec(self, mock_foo_class): mock_foo_obj = mock_foo_class.return_value # create the attribute you need from mocked Foo mock_foo_obj.x ="potato" bar_obj = some_module.Bar() self.assertEqual(bar_obj.c.x, 'potato') self.assertFalse(hasattr(bar_obj.c, 'poof')) |
现在,您的测试将成功通过验证您的
下面是Martijn Pieters的另一个解释,它不一定直接回答您的问题,但给出了一个很好的示例和使用Autospec的解释,可以帮助您进一步理解:
https://stackoverflow.com/a/31710001/1832539