Проверка издевательства на равенство - PullRequest
0 голосов
/ 06 февраля 2020

Есть ли простой способ проверить два unittest.mock.Mock экземпляра на равенство на основе их несвойственных атрибутов? Mock не обеспечивает реализацию __eq__ (и не MagicMock AFAIK), поэтому Mock(a=1) == Mock(a=1) оценивается как False.

Я ищу решение, которое также работает для вложенных mocks, то есть для таких вещей, как Mock(a=Mock(x=1), b=2).

Я пытался использовать dir для перечисления атрибутов mocks, но он также содержит специальные атрибуты, такие как 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))

1 Ответ

0 голосов
/ 06 февраля 2020

Я не могу думать ни о чем, кроме грубой проверки атрибутов.

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

Это должно соответствовать вашим требованиям для простых сценариев использования. В случае, если один макет фактически ссылается на другой, это может go привести к бесконечной рекурсии.

...