为啥 requests-mock 装饰器模式会在 pytest 中抛出“fixture 'm' not found”错误?

Posted

技术标签:

【中文标题】为啥 requests-mock 装饰器模式会在 pytest 中抛出“fixture \'m\' not found”错误?【英文标题】:Why is the requests-mock decorator pattern throwing a "fixture 'm' not found" error with pytest?为什么 requests-mock 装饰器模式会在 pytest 中抛出“fixture 'm' not found”错误? 【发布时间】:2020-05-04 20:48:28 【问题描述】:

我正在使用 requests 库发出 HTTP GET 请求。例如(截断):

requests.get("http://123-fake-api.com")

我已经按照requests-mock decorator 模式编写了一个测试。

import requests
import requests_mock


@requests_mock.Mocker()
def test(m):
    m.get("http://123-fake-api.com", text="Hello!")

    response = requests.get("http://123-fake-api.com").text

    assert response.text == "Hello!"

当我使用pytest 运行测试时,出现以下错误。

E       fixture 'm' not found

为什么 requests-mock 装饰器会抛出“fixture 'm' not found”错误?我该如何解决?

【问题讨论】:

根据文档你说错了,它说像@requests_mock.Mocker()一样调用它 @aws_apprentice 我在使用 @requests_mock.Mocker() 时遇到同样的错误。 @aws_apprentice 你是对的,我的示例与我引用的文档不匹配。我根据 pypi.org/project/requests-mock 上的装饰器示例使用了 @requests_mock.mock()。在你指出之前我没有注意到差异。我根据您的反馈更新了我的示例。 @aws_apprentice 我提交了 PR 以更新 requests-mock 文档:github.com/jamielennox/requests-mock/pull/119。 【参考方案1】:

您收到错误是因为 Python 3 (see GitHub issue) 中无法识别 Requests Mock 装饰器。要解决此错误,请使用How to use pytest capsys on tests that have mocking decorators? 中引用的解决方法。

import requests
import requests_mock


@requests_mock.Mocker(kw="mock")
def test(**kwargs):
    kwargs["mock"].get("http://123-fake-api.com", text="Hello!")

    response = requests.get("http://123-fake-api.com")

    assert response.text == "Hello!"

其他选项

您也可以使用以下替代方法之一。

1。 requests-mock 的 pytest 插件

使用请求模拟作为pytest fixture。

import requests


def test_fixture(requests_mock):
    requests_mock.get("http://123-fake-api.com", text="Hello!")

    response = requests.get("http://123-fake-api.com")

    assert response.text == "Hello!"

2。上下文管理器

使用请求模拟作为context manager。

import requests
import requests_mock


def test_context_manager():
    with requests_mock.Mocker() as mock_request:
        mock_request.get("http://123-fake-api.com", text="Hello!")
        response = requests.get("http://123-fake-api.com")

    assert response.text == "Hello!"

【讨论】:

我不赞成投票,因为虽然您提供的方法是有效的,但您在回答之上所做的陈述是错误的。这适用于 Python 3,并且您链接的问题已关闭,因为它已得到解决。正如我在评论中提到的那样,您根据文档错误地调用了装饰器。 @aws_apprentice 根据***.com/a/52065289/11809808,装饰器只能通过变通方法实现。 @requests_mock.Mocker() 我仍然遇到同样的错误。虽然问题已解决,但解决方案似乎不是修复原始装饰器,而是简单地实现一种调用 requests-mock 的新方法 - 使用 pytest 固定装置。 请编辑您的答案以参考解决方法,我可以删除我的反对票,只有在帖子因 SO 规则而被编辑后才能删除投票,谢谢

以上是关于为啥 requests-mock 装饰器模式会在 pytest 中抛出“fixture 'm' not found”错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们需要装饰器设计模式中的装饰器?

为啥装饰器模式适用于指针而不适用于引用?

为啥我会在装饰器上使用责任链?

装饰器详解

python装饰器

Python 装饰器 - 为啥? [复制]