Python 2.7 模拟/补丁:理解 assert_called_XYZ()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20399327/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python 2.7 mock/patch: understanding assert_called_XYZ()
提问by try-catch-finally
I'm relatively new to Python and unit testing in Python. From the Java world I know the concept of mocking but it seem to be much different from what I can see in Python.
我对 Python 和 Python 中的单元测试比较陌生。从 Java 世界我知道模拟的概念,但它似乎与我在 Python 中看到的有很大不同。
I found this guide, which I found very helpful: http://www.voidspace.org.uk/python/mock/index.html
我找到了这个指南,我觉得它很有帮助:http: //www.voidspace.org.uk/python/mock/index.html
But as I wrote my (a bit more complex) tests with mocked out dependencies I noticed a strage behavior. I decided to create a reduced, simple example which also does not work as I expect it.
但是当我使用模拟依赖项编写我的(稍微复杂一点的)测试时,我注意到了一个奇怪的行为。我决定创建一个简化的、简单的示例,但它也无法按我的预期工作。
Take a look at this, the result and my expectation I have added as comments:
看看这个,结果和我作为评论添加的期望:
import unittest
from mock import patch, Mock, MagicMock
class BasicTest(unittest.TestCase):
@patch("StringIO.StringIO")
def testSomethingNotWorkingAsExpected(self, StringIOMock):
StringIOMock.assert_called_once() # asserts, but why?
@patch("StringIO.StringIO")
def testSomethingSomehowWorking(self, StringIOMock):
# self.instantiateStringIO() # intentionally commented out
assert StringIOMock.called # does not assert (leading to failure of this test); as expected. If the above line is not commented, this asserts as expected.
def instantiateStringIO(self):
import StringIO
StringIO.StringIO()
Why is assert_called_once()asserting the instantiation of StringIOeven it has not been instantiated yet?
And why does assert ClassMock.calledbring the expected results?
为什么assert_called_once()断言它的实例化StringIO甚至还没有被实例化?而为什么会assert ClassMock.called带来预期的结果?
Using assert not ...to assert a method has not been called I found here: Assert a function/method was not called using Mock. I inverted this pattern in my case by omitting the not.
Using assert not ...to assert a method has not been called I found here: Assert a function/method was not called using Mock。在我的案例中,我通过省略not.
Somewhere I found the pattern ClassMock.return_valueto reference an instance. But I understand this as a way to manupulate the instance of a Mock before it will be called, not as a way to access the instance that might an underliing code have internally created. Or am I wrong?
在某处我找到了ClassMock.return_value引用实例的模式。但我理解这是一种在调用 Mock 实例之前对其进行操作的方法,而不是一种访问可能由底层代码在内部创建的实例的方法。还是我错了?
My environment:
我的环境:
- Python 2.7.3
- mock 0.8.8
- Fedora 19
- 蟒蛇 2.7.3
- 模拟 0.8.8
- 软呢帽 19
Probably my understanding of the mock/patch thing is wrong. Could please someone aditionally explain what a class mock does and how it works?
可能我对模拟/补丁的理解是错误的。可以请别人解释一下类模拟的作用以及它是如何工作的吗?
Edit1: Added output
编辑 1:添加输出
... and added paraphrase in parens to comment in testSomethingSomehowWorking
...并在括号中添加释义以评论 testSomethingSomehowWorking
This is the output:
这是输出:
.F
======================================================================
FAIL: testSomethingSomehowWorking (test_test.BasicTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/mock.py", line 1224, in patched
return func(*args, **keywargs)
File "test_test.py", line 15, in testSomethingSomehowWorking
assert StringIOMock.called # does not assert; as expected
AssertionError
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
采纳答案by Simeon Visser
The method assert_called_oncedoes not exist and it does not perform an assertion. It's no different from writing StringIOMock.assert_foo_bar_does_not_exist()or any other method. The mock library doesn't check whether the method called on the mock actually exists.
该方法assert_called_once不存在且不执行断言。这与写作StringIOMock.assert_foo_bar_does_not_exist()或任何其他方法没有什么不同。模拟库不会检查在模拟上调用的方法是否实际存在。
If you use assert_called_once_withthen it fails as expected.
如果您使用,assert_called_once_with那么它会按预期失败。
You can use the specparameter to raise an error when you call a non-existent method:
spec当您调用不存在的方法时,您可以使用该参数引发错误:
@patch("StringIO.StringIO", spec=StringIO.StringIO)
def testSomethingNotWorkingAsExpected(self, StringIOMock):
StringIOMock.assert_called_once() # will fail as the method doesn't exist

