我正在嘲笑一个枚举,所以我可以独立于任何实际值来测试我的代码,但是如果我使用“in”关键字,那么我正在测试的函数中显然会覆盖mock。模拟在我正在测试的函数中可见,我真的不明白为什么会发生这种情况。
这是一个突出我问题的简短示例:
function.py:
from enum import Enum
class TestType(Enum):
APPLE = 1
class CheckTheEnum():
def get_enum_value(self, test_type):
# "test" has a variable "TEST" here.
test = TestType
# this call always fails for the mock, but it works if I execute it for real.
if test_type in TestType:
return test_type.value
else:
raise NameError
test.py:
from unittest import TestCase, main
from unittest.mock import patch
from function import CheckTheEnum
class TestCheckTheEnum(TestCase):
@patch('converter.test.TestType')
def test_get_enum_value(self, mock_testtype):
mock_testtype.TEST = 10
checker = CheckTheEnum()
value = checker.get_enum_value(mock_testtype.TEST)
self.assertEqual(value, 10)
if __name__ == "__main__":
main()
为什么不在这里找到mock_testtype.TEST?
答案 0 :(得分:0)
请注意,在您模拟它之后,您的TestType
对象不再是TestType
,而是unittest.mock.MagicMock
对象,因此您的in
将会失败。
您可以在 TestType 枚举类中添加has_value
方法:
class TestType(Enum):
APPLE = 1
@classmethod
def has_value(cls, value):
return any(value == item.value for item in cls)
然后将您的CheckTheEnum
课程更改为:
class CheckTheEnum():
def get_enum_value(self, test_type):
# this call always fails for the mock, but it works if I execute it for real.
value = TestType.has_value(test_type)
if value:
return value
else:
raise NameError
最后,不要嘲笑Enum模拟has_value
方法:
from unittest import TestCase, main
from unittest.mock import patch
from function import CheckTheEnum
class TestCheckTheEnum(TestCase):
@patch('converter.test.TestType.has_value', return_value=11)
def test_get_enum_value(self, mock_testtype):
checker = CheckTheEnum()
value = checker.get_enum_value(mock_testtype.TEST)
mock_testtype.assert_called_with(mock_testtype.TEST)
self.assertEqual(value, 11)
if __name__ == "__main__":
main()
只要改变它会返回什么。