programing

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

codeshow 2023. 8. 20. 12:54
반응형

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

읽기 전용 속성을 모의로 어떻게 모의합니까?

노력했습니다.

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

속성을 재정의할 개체가 모의 개체인 경우 사용하지 않아도 됩니다.patch.

대신 에 를 만든 다음 모의 유형의 속성을 재정의할 수 있습니다.예를 들어, 재정의 방법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

와 함께 사용하는 경우 코드를 단순화하고 컨텍스트 관리자(즉,with다음과 같은 문장:

def test_name(mocker): # mocker is a fixture included in pytest-mock
    mocked_property = mocker.patch(
        'MyClass.property_to_be_mocked',
        new_callable=mocker.PropertyMock,
        return_value='any desired value'
    )
    o = MyClass()

    print(o.property_to_be_mocked) # this will print: any desired value

    mocked_property.assert_called_once_with()

아마도 스타일의 문제일 것이지만, 시험에서 장식가를 선호하는 경우, @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(self, mock_last_transaction):
        mock_last_transaction.return_value = Transaction()
        myclass = MyClass()
        print myclass.last_transaction
        mock_last_transaction.assert_called_once_with()

만약 당신이 조롱을 필요로 한다면,@property원본에 의존하는__get__사용자 정의를 생성할 수 있습니다.MockProperty

class PropertyMock(mock.Mock):

    def __get__(self, obj, obj_type=None):
        return self(obj, obj_type)

용도:

class A:

  @property
  def f(self):
    return 123


original_get = A.f.__get__

def new_get(self, obj_type=None):
  return f'mocked result: {original_get(self, obj_type)}'


with mock.patch('__main__.A.f', new_callable=PropertyMock) as mock_foo:
  mock_foo.side_effect = new_get
  print(A().f)  # mocked result: 123
  print(mock_foo.call_count)  # 1

조롱당한 속성에 액세스했는지 여부를 테스트하지 않으려면 예상된 속성에 패치를 적용하면 됩니다.return_value.

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

저는 테스트에서 파이썬 버전을 조롱하고 싶어서 이 질문을 받았습니다.이것이 이 질문과 상당히 관련이 있는지는 확실하지 않지만,sys.version읽기 전용임이 분명함(...기술적으로는 "재산"이 아닌 "속성"이지만, 제 생각에는).

그래서, 이 장소를 숙독하고 바보같이 복잡한 것들을 시도한 후에 저는 답이 단순함 그 자체라는 것을 깨달았습니다.

with mock.patch('sys.version', version_tried):
    if version_tried == '2.5.2':
        with pytest.raises(SystemExit):
            import core.__main__
        _, err = capsys.readouterr()
        assert 'FATAL' in err and 'too old' in err

누군가를 도울 수도 있습니다.

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

반응형