【问题标题】:Mock database connection python模拟数据库连接python
【发布时间】:2020-04-19 13:31:21
【问题描述】:

我有一个名为 redis_db.py 的文件,其中包含连接到 redis 的代码

import os
import redis
import sys

class Database:
       def __init__(self, zset_name):
        redis_host = os.environ.get('REDIS_HOST', '127.0.0.1')
        redis_port = os.environ.get('REDIS_PORT', 6379)

        self.db = redis.StrictRedis(host=redis_host, port=redis_port)
        self.zset_name = zset_name

    def add(self, key):
        try:
            self.db.zadd(self.zset_name, {key: 0})
        except redis.exceptions.ConnectionError:
            print("Unable to connect to redis host.")
            sys.exit(0)

我有另一个名为 app.py 的文件,就像这样

from flask import Flask
from redis_db import Database

app = Flask(__name__)
db = Database('zset')

@app.route('/add_word/word=<word>')
def add_word(word):
   db.add(word)
   return ("{} added".format(word))

if __name__ == '__main__':
    app.run(host='0.0.0.0', port='8080')

现在我正在为这样的 add_word 函数编写单元测试

import unittest
import sys
import os
from unittest import mock

sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../api/")
from api import app  # noqa: E402


class Testing(unittest.TestCase):

  def test_add_word(self):
      with mock.patch('app.Database') as mockdb:
         mockdb.return_value.add.return_value = ""
      result = app.add_word('shivam')
      self.assertEqual(result, 'shivam word added.')

我面临的问题是,即使我在模拟 db 方法调用,它仍在调用类中的实际方法,而不是返回模拟值,并且在测试期间我收到消息 Unable to connect to redis host. 的错误。

有人可以帮我弄清楚如何模拟 redis 数据库调用。

我正在使用单元测试模块

【问题讨论】:

  • 问题是您在模块导入时定义了db = Database('zset'),因此您的模拟补丁不会影响您的db 变量。

标签: python python-unittest


【解决方案1】:

问题在于db 是在模块导入时定义的,因此mock.patch 不会影响db 变量。要么你移动实例化 dbadd_word(word) 函数中,或者你修补db 而不是Database,例如

def test_add_word():
    with mock.patch('api.app.db') as mockdb:
        mockdb.add = mock.MagicMock(return_value="your desired return value")
        result = app.add_word('shivam')
    print(result)

注意add_word的调用必须在with块中,否则使用未模拟的版本。

【讨论】:

  • 不行不行,它仍在调用原始代码。 app.py 也是一个烧瓶应用程序,这会影响我测试应用程序的方式吗?
  • 应该没什么区别,尽管对于您发布的测试用例,我的测试函数调用了模拟版本。也许您遗漏了有关您的实施的一些细节?
  • 我已经用与我最后运行的完全相同的代码更新了我的问题。我希望这会有所帮助。
  • 我用我更新的测试函数尝试了你的确切源代码,它工作正常。 test_add_word 函数是类的方法吗?如果是,您可以发布此课程吗?我还认为,app 作为您的烧瓶应用程序和模块名称的双重使用可能会导致问题,尽管它对我有用。
  • 我也用我的测试代码更新了这个问题。我希望这会有所帮助,因为这让我现在发疯了。 :(
猜你喜欢
  • 2011-03-14
  • 2011-08-16
  • 2011-08-23
  • 2011-10-19
  • 2012-01-06
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
相关资源
最近更新 更多