背景
相对较新的Python和它的unittest模块。在测试中模拟静态类变量时遇到问题。
(仅当原始类方法通过其第一个参数:cls引用其自己的类变量时)
示例:
正在测试的类和类方法的简化版本:
a.py
class A:
# class variable
my_list = []
@classmethod
def my_method(cls, item):
print cls # [] unable to mock this, why?
print A # [1,2,3] mocked as intended
cls.my_list.append(item)
测试:
import unittest
from mock import patch
from a import A
class Test(unittest.testCase):
def test_my_method(self):
with patch("a.A") as mock_A:
# mocking the class variable
mock_A.my_list = [1,2,3]
# test call class method
A.my_method(4)
# assert the appended list to expected output
self.assertEqual(mock_A.my_list, [1,2,3,4])
# should evaluate to true, but fails the test
if __name__ == "__main__":
unittest.main()
问题
为什么模拟只修补A引用而不修补cls reference?
发布于 2018-07-15 06:17:50
您已经在测试模块中导入了A
,因此您已经有了对原始的未打补丁的A
的引用,这就是您所说的my_method
on。
因为那是你打的补丁。Patch通过拦截名称查找来工作,它不会(也不能)直接在适当的地方替换对象。当您想修补具有多个名称的对象(在本例中为A
和cls
)时,则必须修补每个名称查找。
直接修补class属性会更好:
class Test(unittest.TestCase):
def test_my_method(self):
with patch("a.A.my_list", [1,2,3]):
A.my_method(4)
self.assertEqual(A.my_list, [1,2,3,4])
self.assertEqual(A.my_list, []) # note: the mock is undone here
https://stackoverflow.com/questions/51343726
复制相似问题