在python中模拟类属性的属性

2024-06-06 00:56:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我在模拟属性时遇到问题

我有以下课程:

import boto3

class QueryFetcher:
    def __init__(self, query: str):
        self._query = query
        self._athena = boto3.client("athena")
    
    @property
    def athena(self):
        return self._athena
    
    def query_athena(self):
        # need to mock start_query_execution function
        execution = self._athena.start_query_execution(. . .)
        execution_id = execution["QueryExecutionId"]

        while True:
            # need to mock get_query_execution function
            stats = self._athena.get_query_execution(QueryExecutionId=execution_id)
            . . .

        return status, execution_id

我必须模拟函数start_query_executionget_query_execution,它们是类中属性athena的一部分

我试图对函数进行单元测试query_athena。这是单元测试的示例文件:

import pytest
from query_fetcher import QueryFetcher
from unittest.mock import patch, PropertyMock


@pytest.fixture
def fetcher_user():
    return QueryFetcher(query="")


@mock.patch(
    "query_fetcher.QueryFetcher.athena",
    new_callable=mock.PropertyMock,
)
def test_query_athena(mock_athena, fetcher_user):
    mock_athena.return_value.get_query_execution.return_value = {
        "QueryExecution": {"Status": {"State": "SUCCEEDED"}}
    }
    mock_athena.return_value.start_query_execution.return_value = {
        "QueryExecutionId": "69320478-2452-465e-bc0d-89cdc8bd4428"
    }
    fetcher_user.query_athena()

但是,这不起作用,我认为这是因为我必须创建该类的新实例。因此,我尝试了以下方法:

@mock.patch(
    "query_fetcher.QueryFetcher.athena",
    new_callable=mock.PropertyMock,
)
def test_query_athena(mock_athena):
    mock_athena.return_value.get_query_execution.return_value = {
        "QueryExecution": {"Status": {"State": "SUCCEEDED"}}
    }
    mock_athena.return_value.start_query_execution.return_value = {
        "QueryExecutionId": "69320478-2452-465e-bc0d-89cdc8bd4428"
    }
    # create a new class instance
    fetcher_user = QueryFetcher(query="")
    fetcher_user.query_athena()

但这也不行。我错过了什么

理想情况下,我希望模拟fixture fetcher_user上的属性athena,而不是完全创建一个新实例。我也不想修改我的装置来模拟装置内部的功能。这可能吗

我非常感谢在这个问题上的任何帮助,谢谢


Tags: importselfgetreturnvaluedefquerymock
1条回答
网友
1楼 · 发布于 2024-06-06 00:56:26

我通过以下操作解决了此问题:

import mock

def test_query_athena(fetcher_user):
    fetcher_user._athena = mock.MagicMock()
    fetcher_user._athena.get_query_execution.return_value = {"QueryExecution": {"Status": {"State": "SUCCEEDED"}}}
    fetcher_user._athena.start_query_execution.return_value = {"QueryExecutionId": "69320478-2452-465e-bc0d-89cdc8bd4428"}
    fetcher_user.query_athena()

这还可以根据我的需要使用夹具,并使事情变得简单:)

相关问题 更多 >