【问题标题】:Flask unit-test: Unable to mock a function in a post request烧瓶单元测试:无法在发布请求中模拟函数
【发布时间】:2021-06-22 07:29:03
【问题描述】:

我有以下烧瓶应用程序。

# app.py

from flask import Flask, request
from predict import query_sku

app = Flask(__name__)

@app.route("/predict", methods=["POST"])
def predict():
    content = request.json
    max_results = content["resultSize"]
    input_sku_list = content["sku"]

    skus = query_sku(input_sku_list, max_results)
    return {"sku": skus}

if __name__ == "__main__":
    app.run()

我使用pytest 为它编写了一个单元测试,并尝试使用unittest.mock 模拟query_sku 函数。

import sys
from unittest.mock import Mock

import pytest

import app

def test_api_mocked_model():
    sys.modules["predict"] = Mock()
    from predict import query_sku
    query_sku.return_value = "dummy"

    with app.app.test_client() as client:
        response = client.post('/predict', json={"resultSize":10,"sku": "x"}).json

    assert response == {"sku": "dummy"}
    del sys.modules['predict']

但我无法在请求中模拟该函数。它只是给出了以下断言错误。

>       assert response == {"sku": "dummy"}
E       AssertionError: assert None == {'sku': 'dummy'}
E         +None
E         -{'sku': 'dummy'}

tests/unit_tests/test_api.py:34: AssertionError

我怎样才能让它工作?

[编辑]

我在下面的query_sku 函数中添加了。有意返回一个与 Mock 函数 return_value 不同的值。

# predict.py
def query_sku(input_sku_list, topn):
    return "actual function"

但是单元测试仍然是从实际函数中查询,如下图。

assert response == {"sku": "dummy"}
E       AssertionError: assert {'sku': 'actual function'} == {'sku': 'dummy'}
E         Differing items:
E         {'sku': 'actual function'} != {'sku': 'dummy'}

【问题讨论】:

    标签: python unit-testing flask mocking


    【解决方案1】:
    from unittest.mock import MagicMock
    
    def test_api_mocked_model():
         ## sys.modules["predict"] = Mock() ## why sys module ?
        from predict import query_sku
        query_sku = MagicMock(return_value="dummy") # mock directly 
      
    
    
        with app.app.test_client() as client:
            response = client.post('/predict', json={"resultSize":10,"sku": "x"}).json
    
        assert response == {"sku": "dummy"}
        del sys.modules['predict']
    

    你能试试这个代码吗?

    【讨论】:

    • 嗨,它为query_sku(mock, "dummy") 行提供了TypeError: query_sku() missing 1 required positional argument: 'topn',因为该函数是实际函数,并且它需要更多参数。我将这些行更改为query_sku = Mock(); query_sku.return_value = "dummy",它模拟了函数和返回值,但它仍然没有模拟到烧瓶请求中的func
    • 你写信给import MagicMock,但它没有在测试功能中使用,这会有所不同吗?
    • 你能用MagicMock再试一次吗?我已经更新了答案
    • 嗯,它给出了同样的错误TypeError: query_sku() missing 1 required positional argument: 'topn' :(
    • 您能否提供定义。函数query_sku,错误原因在你的app.py,而不是测试文件
    猜你喜欢
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2020-09-08
    • 2021-09-30
    • 2019-12-17
    • 1970-01-01
    相关资源
    最近更新 更多