gpt4 book ai didi

python - 是否可以在测试中同时在另一个 fixture 中使用一个 fixture ?

转载 作者:太空狗 更新时间:2023-10-30 00:16:11 27 4
gpt4 key购买 nike

我正在使用 unittest.mock 模拟一个 API。我的界面是一个在后台使用 requests 的类。所以我正在做这样的事情:

@pytest.fixture
def mocked_api_and_requests():
with mock.patch('my.thing.requests') as mock_requests:
mock_requests.post.return_value = good_credentials
api = MyApi(some='values', that='are defaults')
yield api, mock_requests


def test_my_thing_one(mocked_api_and_requests):
api, mocked_requests = mocked_api_and_requests
... # some assertion or another

def test_my_thing_two(mocked_api_and_requests):
api, mocked_requests = mocked_api_and_requests
... # some other assertions that are different

正如您可能看到的那样,我在这两个测试中得到了相同的第一行,而且闻起来对我来说还不够干。

我很想能够做这样的事情:

def test_my_thing_one(mock_requests, logged_in_api):
mock_requests.get.return_value = ...

而不是必须解压这些值,但我不确定是否有一种方法可以使用 pytest 可靠地做到这一点。如果它在 documentation for fixtures 中我完全错过了。但确实感觉应该有一种正确的方法来做我想在这里做的事情。

有什么想法吗?如果我需要走那条路,我愿意使用 class TestGivenLoggedInApiAndMockRequests: ...。我只是不太确定这里的适当模式是什么。

最佳答案

可以通过使用多个 fixtures 来准确地实现您想要的结果。

注意:我对您的示例进行了最低限度的修改,以便我的答案中的代码是独立的,但您应该能够轻松地使其适应您的用例。

myapi.py 中:

import requests

class MyApi:

def get_uuid(self):
return requests.get('http://httpbin.org/uuid').json()['uuid']

test.py 中:

from unittest import mock
import pytest
from myapi import MyApi

FAKE_RESPONSE_PAYLOAD = {
'uuid': '12e77ecf-8ce7-4076-84d2-508a51b1332a',
}

@pytest.fixture
def mocked_requests():
with mock.patch('myapi.requests') as _mocked_requests:
response_mock = mock.Mock()
response_mock.json.return_value = FAKE_RESPONSE_PAYLOAD
_mocked_requests.get.return_value = response_mock
yield _mocked_requests

@pytest.fixture
def api():
return MyApi()

def test_requests_was_called(mocked_requests, api):
assert not mocked_requests.get.called
api.get_uuid()
assert mocked_requests.get.called

def test_uuid_is_returned(mocked_requests, api):
uuid = api.get_uuid()
assert uuid == FAKE_RESPONSE_PAYLOAD['uuid']

def test_actual_api_call(api): # Notice we don't mock anything here!
uuid = api.get_uuid()
assert uuid != FAKE_RESPONSE_PAYLOAD['uuid']

我没有定义一个返回元组的固定装置,而是定义了两个固定装置,测试可以独立使用它们。像这样组合固定装置的一个优点是它们可以独立使用,例如最后一个测试实际上调用了 API,只是因为没有使用 mock_requests fixture。

请注意——要直接回答问题标题——您还可以通过简单地将 mocked_requests 添加到参数中来使 mocked_requests 成为 api fixture 的先决条件,就像这样:

@pytest.fixture
def api(mocked_requests):
return MyApi()

如果您运行测试套件,您会发现它有效,因为 test_actual_api_call 将不再通过。

如果您进行此更改,即使您没有直接指定后者在您的测试函数的参数中。仍然可以明确地使用它,例如如果您想对返回的模拟进行断言。

关于python - 是否可以在测试中同时在另一个 fixture 中使用一个 fixture ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46568060/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com