UserDict在unittest中不被视为字典
import unittest
from UserDict import UserDict
class MyDict(UserDict):
def __init__(self, x):
UserDict.__init__(self, x=x)
class Test(unittest.TestCase):
def test_dict(self):
m = MyDict(42)
assert {'x': 42} == m # this passes
self.assertDictEqual({'x': 42}, m) # failure at here
if __name__ == '__main__':
unittest.main()
我得到了
AssertionError: Second argument is not a dictionary
我应该用内置的 dict
作为基类,而不是 UserDict
吗?
3 个回答
0
来自Python的unittest
源代码
def assertDictEqual(self, d1, d2, msg=None):
self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
这两个参数必须是dict
类型的实例。
而且不幸的是,UserDict
的实例并不是dict
的实例。
assert isinstance(m, dict) # this is False
正如文档中提到的,你可以使用m.data
来返回一个真正的dict
。
IterableUserDict.data
A real dictionary used to store the contents of the UserDict class.
4
问题在于,assertDictEqual()
这个函数首先会检查传入的两个参数是否都是 dict
类型的对象:
def assertDictEqual(self, d1, d2, msg=None):
self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
...
而 UserDict
并不是 dict
类型的对象:
>>> m = UserDict(x=42)
>>> m
{'x': 42}
>>> isinstance(m, dict)
False
所以,不要直接使用 UserDict
类,而是应该使用它的 data
属性,这个属性里面包含了一个真正的字典:
self.assertDictEqual({'x': 42}, m.data)
或者,正如其他人已经建议的那样,直接使用普通的字典就可以了。