首页 > 解决方案 > 检查模拟是否相等

问题描述

有没有一种简单的方法可以unittest.mock.Mock根据它们的非特殊属性检查两个实例是否相等?Mock不提供__eq__实现(MagicMockAFAIK 也不提供),因此Mock(a=1) == Mock(a=1)评估为False.

我正在寻找一种也适用于嵌套模拟的解决方案,即适用于Mock(a=Mock(x=1), b=2).

我尝试使用dir来列出模拟的属性,但它也包含特殊属性method_calls,例如我想忽略的。我也不喜欢硬编码和删除特殊属性。

准确地说,我希望返回以下内容True

m1 = Mock(a=1, b=Mock(c=2))
m2 = Mock(a=1, b=Mock(c=2))
m1.some_method()
compare_mocks(m1, m2)

而以下应该返回False(不同的值.b.c):

compare_mocks(Mock(a=1, b=Mock(c=2)), Mock(a=1, b=Mock(c=3))

标签: pythonmocking

解决方案


除了蛮力检查属性,我想不出任何东西。

def mock_attrs_eq(m1, m2):
    new = type(m1)()
    m1_dir = sorted(set(dir(m1)) - set(dir(new)))
    m2_dir = sorted(set(dir(m2)) - set(dir(new)))
    if len(m1_dir) != len(m2_dir):
        return False
    for name1, name2 in zip(m1_dir, m2_dir):
        if name1 != name2:
            return False
        attr1 = getattr(m1, name1)
        attr2 = getattr(m2, name2)
        typenames = {attr1.__class__.__name__, attr2.__class__.__name__}
        if typenames == {new.__class__.__name__}:
            if not mock_attrs_eq(attr1, attr2):
                return False
        else:
            if attr1 != attr2:
                return False
    return True

这应该满足您对简单用例的要求。在一个模拟实际引用另一个模拟的情况下,这可能会进入无限递归。


推荐阅读