Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中,单元测试模拟在RESTAPI请求上失败_Python_Unit Testing_Mocking_Pytest - Fatal编程技术网

在Python中,单元测试模拟在RESTAPI请求上失败

在Python中,单元测试模拟在RESTAPI请求上失败,python,unit-testing,mocking,pytest,Python,Unit Testing,Mocking,Pytest,大家好,我是单元测试新手,我正在深入研究mock和pytest。我正在尝试对两个rest api请求进行单元测试,其中GET请求检查api中是否不存在项,以及它是否使用POST请求创建项并创建文件夹,否则它是否存在只是为了创建文件夹 我试图使用Mocker(),当我试图模拟GET请求时,我被困在属性错误:Mocker上 这是我试图测试的代码: client = requests.session() # get item by name response = client.

大家好,我是单元测试新手,我正在深入研究mock和pytest。我正在尝试对两个rest api请求进行单元测试,其中GET请求检查api中是否不存在项,以及它是否使用POST请求创建项并创建文件夹,否则它是否存在只是为了创建文件夹

我试图使用
Mocker()
,当我试图模拟
GET
请求时,我被困在
属性错误:Mocker

这是我试图测试的代码:


   client = requests.session()
    # get item by name
    response = client.get(
        f"https://url.com/rest/item/info?name=test_item",
        auth=username, password),
    )

    if (
        response.status_code == 200
        and response.json()["status"]
        == "Item doesn't exist!"
    ):
        logging.info(f"Creating item")
        client.post(
            "https://url.com/rest/item/create?name=test_item",
            auth=username, password),
        )
        # directory creation
        dir_make = "mkdir -p test_item/temperature"
        exec_cmd(dir_make)

    elif response.status_code == 200 and response.json()["status"]=="OK":
        # directory creation
        dir_make = "mkdir -p test_item/temperature"
        exec_cmd(dir_make)

这是因
属性错误而失败的单元测试:

def test_existing_item(requests_mock, monkeypatch):
    with requests_mock.Mocker() as mock:
        mock.get("https://url.com/rest/item/info?name=test_item", text="OK")

        resp = requests.get("https://url.com/rest/item/info?name=test_item")
        assert resp.text == "OK"

编辑:未找到项的测试和
POST
mock。它似乎没有为
else
语句添加覆盖范围。如果项目存在,并且在这种情况下只需要添加文件夹,如何进行测试

def test_existing_item(monkeypatch):
    with requests_mock.Mocker() as mock_request:
        mock_request.get(requests_mock.ANY, text="success!")
        resp = requests.get(
            "https://url.com/rest/item/info?name=test_item",
            auth=("mock_username", "mock_password"),
        )
        if resp.status_code == 200 and resp.json()["status"] == "OK":
            dir_make = "mkdir -p test_item/temperature"
            exec_cmd(dir_make)


    encoded_auth = b64encode(b"mock_username:mock_password").decode("ascii")

    assert mock_request.last_request.headers["Authorization"] == f"Basic {encoded_auth}"


def test_post_item(monkeypatch):
    with requests_mock.Mocker() as mock_request:
        mock_request.get(requests_mock.ANY, text="success!")
        resp = requests.get(
            "https://url.com/rest/item/info?name=test_item",
            auth=("mock_username", "mock_password"),
        )

        if resp.status_code == 200 and resp.json()["status"] == "ERROR":
            mock_request.get(requests_mock.ANY, text="success!")
            requests.post(
                "https://url.com/rest/item/create?name=test_item",
                auth=("mock_username", "mock_password"),
            )

        dir_make = "mkdir -p test_item/temperature"
        exec_cmd(dir_make)


    encoded_auth = b64encode(b"mock_username:mock_password").decode("ascii")

    assert mock_request.last_request.headers["Authorization"] == f"Basic {encoded_auth}"
编辑2:添加了
elif
语句而不是
else
和两个单独的测试,仍然是一个
test\u现有的项目()
没有覆盖
elif
语句…在这种情况下我做错了什么

def test_existing_item(monkeypatch):
    with requests_mock.Mocker() as mock_request:
        mock_request.get(requests_mock.ANY, text="success!")
        resp = requests.get(
            "https://url.com/rest/item/info?name=test_item",
            auth=("mock_username", "mock_password"),
        )
        if resp.status_code == 200 and resp.json()["status"] == "OK":
            dir_make = "mkdir -p test_item/temperature"
            exec_cmd(dir_make)


    encoded_auth = b64encode(b"mock_username:mock_password").decode("ascii")

    assert mock_request.last_request.headers["Authorization"] == f"Basic {encoded_auth}"


def test_post_item(monkeypatch):
    with requests_mock.Mocker() as mock_request:
        mock_request.get(requests_mock.ANY, text="success!")
        resp = requests.get(
            "https://url.com/rest/item/info?name=test_item",
            auth=("mock_username", "mock_password"),
        )

        if resp.status_code == 200 and resp.json()["status"] == "ERROR":
            mock_request.get(requests_mock.ANY, text="success!")
            requests.post(
                "https://url.com/rest/item/create?name=test_item",
                auth=("mock_username", "mock_password"),
            )

        dir_make = "mkdir -p test_item/temperature"
        exec_cmd(dir_make)


    encoded_auth = b64encode(b"mock_username:mock_password").decode("ascii")

    assert mock_request.last_request.headers["Authorization"] == f"Basic {encoded_auth}"
我不熟悉单元测试,所以如果您能帮助我对这段代码进行单元测试,我将不胜感激

import requests
import requests_mock


def test_existing_item(monkeypatch):
    with requests_mock.Mocker() as mock:
        mock.get("https://url.com/rest/item/info?name=test_item", text="OK")

        resp = requests.get("https://url.com/rest/item/info?name=test_item")
        assert resp.text == "OK"
不要将
请求\u mock
作为参数传递,
pytest
应该可以正常工作

编辑:

至于你的编辑:

似乎它没有为else语句添加覆盖范围。如果项目存在,并且在这种情况下只需要添加文件夹,如何进行测试

def test_existing_item(monkeypatch):
    with requests_mock.Mocker() as mock_request:
        mock_request.get(requests_mock.ANY, text="success!")
        resp = requests.get(
            "https://url.com/rest/item/info?name=test_item",
            auth=("mock_username", "mock_password"),
        )
        if resp.status_code == 200 and resp.json()["status"] == "OK":
            dir_make = "mkdir -p test_item/temperature"
            exec_cmd(dir_make)


    encoded_auth = b64encode(b"mock_username:mock_password").decode("ascii")

    assert mock_request.last_request.headers["Authorization"] == f"Basic {encoded_auth}"


def test_post_item(monkeypatch):
    with requests_mock.Mocker() as mock_request:
        mock_request.get(requests_mock.ANY, text="success!")
        resp = requests.get(
            "https://url.com/rest/item/info?name=test_item",
            auth=("mock_username", "mock_password"),
        )

        if resp.status_code == 200 and resp.json()["status"] == "ERROR":
            mock_request.get(requests_mock.ANY, text="success!")
            requests.post(
                "https://url.com/rest/item/create?name=test_item",
                auth=("mock_username", "mock_password"),
            )

        dir_make = "mkdir -p test_item/temperature"
        exec_cmd(dir_make)


    encoded_auth = b64encode(b"mock_username:mock_password").decode("ascii")

    assert mock_request.last_request.headers["Authorization"] == f"Basic {encoded_auth}"

这是因为您的
if
条件始终为true,因此它从不访问
else
语句下面的代码。你的第二个问题我不太清楚,但我相信你想写几个测试,一个测试你的
if
语句,另一个测试你的
else
语句。根据经验,如果在测试中需要条件逻辑,那么您会遇到一个问题:要么每次运行测试时一切都按您所希望的那样进行,要么中止并使测试失败,因为您希望代码在每次运行时都具有完全相同的行为—以及您的测试,作为扩展。

@JohnyMostoq如果在我发送的代码中替换
.get()
调用
.post()
调用,它也会工作得很好。如果这还不足以测试您的代码,那么我想看看您在您所使用的代码上运行的测试sent@JohnyMostoq我编辑了我的评论。我希望这回答了你的问题我按照你的建议做了,分为两个测试,对于同一段代码我得到了相同的结果(没有覆盖范围,只要该项存在)。。。我用单独的测试和代码更改更新了这个问题。我并没有完全理解你所说的“如果你在测试中需要条件逻辑,你就有问题”是什么意思,在单元测试中有条件是一种不好的做法吗?@JohnyMostoq我想这是一个观点问题,但我觉得大多数人会称之为不好的做法。测试的目的是确保代码以特定的方式运行并返回特定的值。如果您有条件逻辑,即使每次都以相同的方式调用它,它的行为或输出也会在多次运行时发生变化-这意味着您需要重构代码以防止出现这种情况-或者永远不会输入一个条件,因此如果您希望两段代码(每个分支一段)都执行,你需要把它分成两个测试,两个测试都要事先相应地修改环境。@JohnyMostoq至于你的主要问题,它们在你的机器上失败了吗?如何检测覆盖率?