使用字典的__repr__进行单元测试的正确方法

12

假设我有一个给定的类:

class MyClass:
    def __init__(self, **kwargs):
        self.kwargs = kwargs
    def __repr__(self):
        return "<%s: %r>" % (self.__class__.__name__, self.kwargs)

__repr__对于核心功能并不是很重要,但有时会被用于日志记录、堆栈跟踪等,因此我想对其进行单元测试。

这个问题类似于使用doctest时遇到的问题, 但我更愿意将任何复杂性(如排序)放在测试函数中,而不是放在__repr__中。

目前,我正在使用evalrerepr()调用中提取字典,但我想检查是否有人使用非eval的替代方法。

def test_repr():
    retval = repr(MyClass(a=1, b=2, c=3))
    match = re.match("^<MyClass: ({.*})>\Z", retval)
    assert match
    assert eval(match.group(1)) == dict(a=1, b=2, c=3)
1个回答

17

你只需要检查kwargs字典是否被正确地显示在输出中,因此只需传递零个或一个关键字参数:

>>> repr(MyClass(foo='bar')) == "<MyClass: {'foo': 'bar'}>"
True
>>> repr(MyClass()) == '<MyClass: {}>'
True

那么顺序根本不重要。


如果您决定坚持评估提取的词典,请改用ast.literal_eval而不是纯粹的eval。我还建议使用切片而不是re,因为您知道预期的格式:

>>> '<MyClass: {}>'[10:-1]
'{}'

在实际代码中,kwargs 是构建而不是简单传入的,因此我无法使用单键或空字典进行测试。不过,literal_eval 是一个好的提示。谢谢! - Felipe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接