对于在一个视图中多次使用的函数,我可以将参数传递给 Monkeypatch.setattr 中的函数吗?

问题描述 投票:0回答:2

我的 Web 应用程序对 Spotify 进行 API 调用。在我的 Flask 视图之一中,我对不同的端点使用相同的方法。具体来说:

sh = SpotifyHelper()
...
@bp.route('/profile', methods=['GET', 'POST'])
@login_required
def profile():
...
    profile = sh.get_data(header, 'profile_endpoint')
    ...
    playlist = sh.get_data(header, 'playlist_endpoint')
    ...
    # There are 3 more like this to different endpoints -- history, top_artists, top_tracks
    ...
    return render_template(
        'profile.html',
        playlists=playlists['items'],
        history=history['items'],
        ...
        )

我不想在测试期间进行 API 调用,因此我编写了一个 mock.json 来替换 API 的 JSON 响应。当每个视图仅使用该方法一次时,我已经成功完成了此操作:

class MockResponse:
@staticmethod
def profile_response():
    with open(path + '/music_app/static/JSON/mock.json') as f:
        response = json.load(f)
    return response

@pytest.fixture
def mock_profile(monkeypatch):
    def mock_json(*args, **kwargs):
        return MockResponse.profile_response()

    monkeypatch.setattr(sh, "get_data", mock_json)

我的问题是我需要以不同的响应调用

get_data
到不同的端点。我的mock.json是这么写的:

{'playlists': {'items': [# List of playlist data]},
 'history': {'items': [# List of playlist data]},
  ...

因此,对于每个 API 端点,我需要类似的东西

playlists = mock_json['playlists']
history = mock_json['history']

我可以写

mock_playlists()
mock_history()
等,但是如何为每个写一个monkeypatch?有没有办法将端点参数传递给
monkeypatch.setattr(sh, "get_data", mock_???)

flask pytest monkeypatching
2个回答
0
投票
from unittest.mock import MagicMock



#other code...

mocked_response = MagicMock(side_effect=[
    # write it in the order of calls you need
    profile_responce_1, profile_response_2 ... profile_response_n
])

monkeypatch.setattr(sh, "get_data", mocked_response)

0
投票

使用参数模拟函数的示例

"""my_module.py"""

def original_func(arg1, arg2):
    print(f'original func, arg1: {arg1} and arg2 {arg2}')

def use_original_func():
    arg1 = "modified_arg1_by_use_original_func"
    arg2 = "modified_arg2_by_use_original_func"
    original_func(arg1, arg2)


"""mock_demo.py"""

import pytest

import my_module
@pytest.fixture
def mock_original_func(monkeypatch):
    def mock_query(arg1, *args, **kwargs):
        print("Mocking original_func")
        print(arg1, "mocked_arg2")

    monkeypatch.setattr(my_module, 'original_func', mock_query)


def test_use_original_func(mock_original_func):
    my_module.use_original_func()

 ### Output
 ============================= test session starts 
 ==============================
 collecting ... collected 1 item

 mock_demo.py::test_use_original_func PASSED                              
 [100%]Mocking original_func
 modified_arg1_by_use_original_func mocked_arg2


 ============================== 1 passed in 0.01s 
 ===============================

Process finished with exit code 0
© www.soinside.com 2019 - 2024. All rights reserved.