Как мне издеваться над методом, созданным декоратором @patch? - PullRequest
1 голос
/ 11 июня 2019

Я пытаюсь использовать @patch декораторы и макеты объектов для проверки поведения моего кода, потребляющего некоторые библиотеки.К сожалению, я не вижу способа сделать то, что я пытаюсь сделать, используя только декораторы, и кажется, что я должен быть в состоянии.Я понимаю, что, как правило, меня больше интересует возвращаемое значение метода, чем конкретная последовательность вызовов, которые он делает в библиотеку, но очень сложно написать тест для сравнения одного изображения с другим.

IЯ подумал, что, возможно, я мог бы создать экземпляры моих фиктивных объектов и затем использовать @patch.object(...), но это не сработало, и, очевидно, @patch('MockObject.method') будет только имитировать методы класса.Я могу заставить код работать, используя with patch.object(someMock.return_value, 'method') as mockName, но это усложняет мои тесты.

from some.module import SomeClass


class MockObject:
    def method(self):
        pass


class TestClass:
    @patch('SomeClass.open', return_value=MockObject())
    @patch('??????.method')  # I can't find any value to put here that works
    def test_as_desired(self, mockMethod, mockOpen):
        instance = SomeClass.open()
        instance.method()

        mockOpen.assert_called_once()
        mockMethod.assert_called_once()

    @patch('SomeClass.open', return_value=MockObject())
    def test_messy(self, mockOpen):
        with patch.object(mockOpen.return_value, 'method') as mockMethod:
            instance = SomeClass.open()
            instance.method()

            mockOpen.assert_called_once()
            mockMethod.assert_called_once()

1 Ответ

1 голос
/ 11 июня 2019

Я думаю, вы слишком усложняете вещи:

import unittest.mock

@unittest.mock.patch.object(SomeClass, open=mock.Mock())
def test_as_desired(self, mock_open):
    instance = SomeClass.open()  # SomeClass.open is a mock, so its return value is too
    instance.method()

    mock_ppen.assert_called_once()
    instance.method.assert_called_once()
...