【问题标题】:Mocking module global variable while import导入时模拟模块全局变量
【发布时间】:2018-11-21 14:54:55
【问题描述】:

我正在为连接到 MongoDB 的 api 编写单元测试。在我的 API 模块中,它看起来像这样:

from flask import Flask, jsonify
from MyApp import MongoData

api = Flask(__name__)
DB_CONN = MongoData()

@api.route('/bla', methods=['GET'])
def alive():
    return jsonify({'response': true})

在我的单元测试中导入此模块时遇到问题。我想用特殊的模拟类模拟来自 MongoData() 的集合,该模拟类使用 mongomock。问题是在测试中导入时我无法模拟 DB_CONN:

from MyApp import api

我试图用模拟来做到这一点:

DB_CONN = MockMongoData()
with mock.patch('MyApp.api.DB_CONN', DB_CONN):
    from MyApp import api

但它仍然尝试连接到配置文件中指定的数据库。

关于如何从 MyApp.api 模块模拟 DB_CONN 有什么建议吗?

提前致谢!

编辑:

这将起作用:

import sys    
from MyApp import MongoData, MockMongoData
sys.modules['MyApp'].MongoData = MockMongoData
from MyApp import api

但是有没有更好(更pythonic)的方法来做到这一点?

【问题讨论】:

  • 您正在模拟对象 MyApp.api.DB_CONN 并将其一起导入。尝试只是模拟,而不是导入
  • 我正在从 MyApp.api 导入所有内容,以及我想要测试的方法,因此模拟而不是导入将不起作用。方法取决于与数据库的连接,因此我必须在我正在导入的模块“内部”模拟 DB_CONN。

标签: python python-3.x api unit-testing flask


【解决方案1】:

先导入模块,再monkeypatch其成员:

DB_CONN = MockMongoData()

from MyApp import api

with mock.patch('MyApp.api.DB_CONN', DB_CONN):
    api.run()

【讨论】:

  • 问题是解释器在执行from MyApp import api时创建了MongoData类的实例。
  • 实例将被遮蔽,所以它只是空闲并且什么都不做。如果您根本不希望创建实例,请将其移至 __name__ == "__main__" 块或用于启动服务器的任何内容中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-18
  • 2021-01-27
  • 1970-01-01
  • 2016-11-15
相关资源
最近更新 更多