읽기 전용 속성을 모의로 모의하는 방법은 무엇입니까?
읽기 전용 속성을 모의로 어떻게 모의합니까?
노력했습니다.
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
'programing' 카테고리의 다른 글
pip을 사용하여 패키지의 여러 버전 설치 (0) | 2023.08.20 |
---|---|
JqGrid를 사용하여 select2 드롭다운의 선택된 값을 변경하려면 어떻게 해야 합니까? (0) | 2023.08.20 |
jQuery로 단어 강조 표시 (0) | 2023.08.15 |
@Configuration 클래스에서 @PostConstruct의 예상 동작은 무엇입니까? (0) | 2023.08.15 |
마리아의 이진 일치에 대한 JPA 메서드 서명DB (0) | 2023.08.15 |