【问题标题】:Flask: Mock call to external component returns a non serializable object for a HTTP responseFlask:对外部组件的模拟调用为 HTTP 响应返回一个不可序列化的对象
【发布时间】:2016-10-20 04:16:57
【问题描述】:

我正在尝试学习如何在 python 中使用 Mock 库。

我有一个通过 redis-py 包连接到 Redis 的 Flask 应用程序。

在我的应用程序的“/myapp/version”API 中,我从 redis-py 调用 info(),并格式化返回的 HTTP 响应,其中 JSON 数据还包括 info() 调用的返回数据:

from flask import Flask, jsonify
from redis import StrictRedis

app = Flask(__name__)
redis = StrictRedis(host='redis', port=6379)

@app.route('/myapp/version', methods=['GET'])
def get_version():
    redis_info = redis.info() #returns a dict
    return jsonify({
        'app_version': '0.1',
        'flask_version': '0.11.1',
        'redis_info': redis_info
    })

这是我的 test.py,它使用了 Flask test_client:

import json
import mock
import redis
import myapp import app

class TestApp:
    @classmethod
    def setup_class(self):
        self.client = app.test_client()
        self.client.testing = True

    @mock.patch.object(redis.StrictRedis, 'info')
    def test_get_version(self, mock_info):
        result = self.client.get('/myapp/version')
        assert result.status_code == 200
        mock_info.assert_called()

如果我启动鼻子测试,来自 HTTP 请求的响应将返回错误:

TypeError: <MagicMock name='info()' id='140548379595472'> is not JSON serializable

我猜问题是 info() 调用被正确地模拟了,但是它不能被序列化为 JSON 以格式化 Flask 测试客户端的响应。

有没有办法获得有效的响应?或者,也许我以错误的方式使用 Mock?我知道它在单元测试中很方便,但在这里它更像是集成测试。

【问题讨论】:

    标签: python json flask redis mocking


    【解决方案1】:

    模拟redis-py 包的最佳方法是使用mockredis。您只需使用:@patch('redis.StrictRedis', mock_strict_redis_client) 修补您的方法。更多信息可以在项目page中找到。

    修补redis 后,您可以设置应用程序所需的特定键的值,就像使用redis 一样。这将使您能够控制应从各种 redis 调用中返回哪些值,并确保您的应用程序能够正常工作。

    在您的特定情况下,在您的应用中某处对 redis 的调用可能会返回魔术模拟,而不是一些可序列化的 json

    可以通过mock_info.return_value = json_str控制调用的返回值

    【讨论】:

    • 非常有趣。如果我理解正确,在这种情况下,@patch 会从实际的 StrictRedis 调用对存根进行某种依赖覆盖,如果我理解正确的话?
    • 正确。存根是您作为参数添加到测试方法的对象。 (我用一种控制这种调用的返回值的方法更新了我的答案)
    • 不好的一面是这个包 mockredis 有一个不存在的文档。只是 30 行的自述文件 :( 我将不得不尝试直接从代码中了解如何使用。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 2017-11-09
    • 1970-01-01
    • 2014-08-14
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多