【问题标题】:mocking environment variables during testing在测试期间模拟环境变量
【发布时间】:2021-02-16 14:53:05
【问题描述】:

我有一个非常简单的 fastapi 应用程序,我想测试它,dummy_api.py 的代码如下:

import os
from fastapi import FastAPI


app = FastAPI()


@app.get(os.getenv("ENDPOINT", "/get"))
def func():
    return {
        "message": "Endpoint working !!!"
    }

当我想对此进行测试时,我正在使用以下文件:

from fastapi.testclient import TestClient
import dummy_api


def test_dummy_api():
    client = TestClient(dummy_api.app)
    response = client.get("/get")
    assert response.status_code == 200


def test_dummy_api_with_envar(monkeypatch):
    monkeypatch.setenv("ENDPOINT", "dummy")
    client = TestClient(dummy_api.app)
    response = client.get("/dummy")
    assert response.status_code == 200

但是我无法模拟环境变量部分,因为其中一个测试以404 失败。

pytest -s -v
================================================================= test session starts ==================================================================
platform linux -- Python 3.8.5, pytest-6.2.2, py-1.9.0, pluggy-0.13.1 -- /home/subhayan/anaconda3/envs/fastapi/bin/python
cachedir: .pytest_cache
rootdir: /home/subhayan/Codes/ai4bd/roughdir
collected 2 items                                                                                                                                      

test_dummy_api.py::test_dummy_api PASSED
test_dummy_api.py::test_dummy_api_with_envar FAILED

======================================================================= FAILURES =======================================================================
______________________________________________________________ test_dummy_api_with_envar _______________________________________________________________

monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ff8c4cf1430>

    def test_dummy_api_with_envar(monkeypatch):
        monkeypatch.setenv("ENDPOINT", "dummy")
        client = TestClient(dummy_api.app)
        response = client.get("/dummy")
>       assert response.status_code == 200
E       assert 404 == 200
E         +404
E         -200

test_dummy_api.py:15: AssertionError
=============================================================== short test summary info ================================================================
FAILED test_dummy_api.py::test_dummy_api_with_envar - assert 404 == 200
============================================================= 1 failed, 1 passed in 0.19s ==============================================================

谁能指出我哪里出错了!!

【问题讨论】:

    标签: python mocking pytest fastapi pytest-mock


    【解决方案1】:

    您可以使用parametrized fixturesimportlib.reload function 来测试确实使用了该环境变量。

    我的测试目录如下所示:

    .
    └── tests
        ├── conftest.py
        ├── dummy_api.py
        └── test_api.py
    

    这是我的conftest.py

    import pytest
    from fastapi.testclient import TestClient
    from importlib import reload
    import dummy_api
    
    
    @pytest.fixture(params=["/get", "/dummy", "/other"])
    def endpoint(request, monkeypatch):
        monkeypatch.setenv("ENDPOINT", request.param)
        return request.param
    
    
    @pytest.fixture()
    def client(endpoint):
        app = reload(dummy_api).app
        yield TestClient(app=app)
    
    

    这里是test_api.py 文件:

    import os
    
    
    def test_dummy_api(client):
        endpoint = os.environ["ENDPOINT"]
        response = client.get(endpoint)
        assert response.status_code == 200
        assert response.json() == {"message": f"Endpoint {endpoint} working !"}
    

    运行pytest后的测试输出:

    collected 3 items                                                                                                                                    
    
    tests/test_api.py::test_dummy_api[/get] PASSED                                                                                                   [ 33%]
    tests/test_api.py::test_dummy_api[/dummy] PASSED                                                                                                  [ 66%]
    tests/test_api.py::test_dummy_api[/other] PASSED                                                                                                  [100%]
    

    【讨论】:

      【解决方案2】:

      在我看来是这样的:

      • 当测试文件被 pytest 加载后,所有可以在 dummy_api 中执行的东西都会被执行,因为它是导入的。
      • 这意味着装饰函数的装饰器(即@app.get(...))将被执行。目前猴子补丁还没有开始。
      • 一旦测试功能启动,环境变量就设置得太晚了。

      【讨论】:

      • 任何想法如何改变它?
      猜你喜欢
      • 2022-08-11
      • 1970-01-01
      • 2023-03-29
      • 2018-11-23
      • 2017-10-04
      • 2021-10-11
      • 2021-09-28
      • 2018-12-18
      • 1970-01-01
      相关资源
      最近更新 更多