Programing

mock으로 읽기 전용 속성을 모의하는 방법은 무엇입니까?

lottogame 2020. 10. 21. 07:34
반응형

mock으로 읽기 전용 속성을 모의하는 방법은 무엇입니까?


mock을 사용하여 readonly 속성을 어떻게 조롱 합니까?

나는 시도했다 :

setattr(obj.__class__, 'property_to_be_mocked', mock.Mock())

그러나 문제는 그것이 클래스의 모든 인스턴스에 적용된다는 것입니다.

다른 생각이 있습니까? 나는 전체 객체를 조롱하는 것이 아니라이 특정 속성 만 모의하고 싶습니다.


더 나은 방법은 메서드를 직접 PropertyMock조롱하는 것보다 속성을로 조롱하는 __get__것입니다.

문서에 명시되어 있습니다 . 검색 unittest.mock.PropertyMock: 클래스에서 속성 또는 기타 설명 자로 사용하기위한 모의. 가져올 때 반환 값을 지정할 수 있도록 메서드를 PropertyMock제공합니다 .__get____set__

방법은 다음과 같습니다.

class MyClass:
    @property
    def last_transaction(self):
        # an expensive and complicated DB query here
        pass

def test(unittest.TestCase):
    with mock.patch('MyClass.last_transaction', new_callable=PropertyMock) as mock_last_transaction:
        mock_last_transaction.return_value = Transaction()
        myclass = MyClass()
        print myclass.last_transaction
        mock_last_transaction.assert_called_once_with()

사실, 대답은 (평소처럼) 문서 에 있었는데, 예제를 따랐을 때 클래스 대신 인스턴스에 패치를 적용하고 있었기 때문입니다.

방법은 다음과 같습니다.

class MyClass:
    @property
    def last_transaction(self):
        # an expensive and complicated DB query here
        pass

테스트 스위트에서 :

def test():
    # Make sure you patch on MyClass, not on a MyClass instance, otherwise
    # you'll get an AttributeError, because mock is using settattr and
    # last_transaction is a readonly property so there's no setter.
    with mock.patch(MyClass, 'last_transaction') as mock_last_transaction:
        mock_last_transaction.__get__ = mock.Mock(return_value=Transaction())
        myclass = MyClass()
        print myclass.last_transaction

아마도 스타일의 문제이지만 테스트에서 데코레이터를 선호하는 경우 @jamescastlefield의 답변 을 다음과 같이 변경할 수 있습니다.

class MyClass:
    @property
    def last_transaction(self):
        # an expensive and complicated DB query here
        pass

class Test(unittest.TestCase):
    @mock.patch('MyClass.last_transaction', new_callable=PropertyMock)
    def test(mock_last_transaction):
        mock_last_transaction.return_value = Transaction()
        myclass = MyClass()
        print myclass.last_transaction
        mock_last_transaction.assert_called_once_with()

재정의하려는 속성이있는 개체가 모의 개체 인 경우을 사용할 필요가 없습니다 patch.

대신 모의 유형 에 대한 PropertyMock속성을 만든 다음 재정의 할 수 있습니다 . 예를 들어 속성을 재정 의하여 반환하려면 다음을 수행하십시오.mock_rows.pages(mock_page, mock_page,)

mock_page = mock.create_autospec(reader.ReadRowsPage)
# TODO: set up mock_page.
mock_pages = mock.PropertyMock(return_value=(mock_page, mock_page,))
type(mock_rows).pages = mock_pages

If you don't want to test whether or not the mocked property was accessed you can simply patch it with the expected return_value.

with mock.patch(MyClass, 'last_transaction', Transaction()):
    ...

참고URL : https://stackoverflow.com/questions/11836436/how-to-mock-a-readonly-property-with-mock

반응형