首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用"from .“导入实例变量时,是否有一种方法来模拟实例变量在蟒蛇里?

在使用"from .“导入实例变量时,是否有一种方法来模拟实例变量在蟒蛇里?
EN

Stack Overflow用户
提问于 2022-08-17 18:38:36
回答 1查看 86关注 0票数 0

对于pytest来说,下面是我用来模拟MongoDB连接的代码片段。

我的Mongo连接实用程序,它由我的所有数据层使用:

connection_util.py

代码语言:javascript
复制
from pymongo import MongoClient

mongo_connection = MongoClient()

这是我的DAO层之一,用来获取学生信息:

student_dao.py

代码语言:javascript
复制
from connection_util import mongo_connection

class StudentDAO:

    def get_student_info(self, student_id):
        student_table = mongo_connection['test_db']['student']
        student_data = student_table.find_one({"_id": student_id})
        return student_data

我的pytest conftest文件,其中包含mongomock连接夹具:

conftest.py

代码语言:javascript
复制
import mongomock
import pytest

@pytest.fixture(scope='class', autouse=True)
def patch_mongo():
    mongo_connection = mongomock.MongoClient()
    
    yield mongo_connection
    
    mongo_connection.drop_database('mongodb')
    mongo_connection.drop_database('testdb')
    mongo_connection.close()

我的测试文件。在这里,我试图用Mongomock实例来模拟实际的mongo_connection实例:

test_student.py

代码语言:javascript
复制
import connection_util
from student_dao import StudentDAO

@pytest.mark.usefixtures("patch_mongo")
class TestStudent:

    def test_student(self, patch_mongo):
        with patch.object(connection_util, "mongo_connection", patch_mongo):
            student_id = "123546"
            student = StudentDAO()
            student_data = student.get_student_info("123546")
            assert student_id == student_data.get("_id")

patch.object中,我的目标是connection_util,我的属性是mongo_connection,我的新变量是patch_mongo(pytest fixture)。它成功地将我的mongo_connection变量模拟为pymongo MongoClient,并在with语句中工作。但在我的studentdao.py中,它仍然指的是MongoClient,而不是mongomock MongoClient。

当我将connection_util在student_dao.py中的导入语句从"from connection_util import mongo_connection"更改为"import connection_util"并将"mongo_connection"更改为"connection_util.mongo_connection"时,它是正确工作的。下面的代码起作用。它将pymongo MongoClient替换为mongomock MongoClient。

代码语言:javascript
复制
import connection_util

class StudentDAO:

    def get_student_info(self, student_id):
        student_table = connection_util.mongo_connection['test_db']['student']
        student_data = student_table.find_one({"_id": student_id})
        return student_data

这里的问题是,我不能对我的所有DAO层进行这些更改,因为有很多文件,手动执行也需要更多的时间。是否有一种不替换导入语句来模拟mongo_connection实例的方法?

EN

回答 1

Stack Overflow用户

发布于 2022-08-18 20:37:56

测试中的主要问题是修补错误的对象。这在打补丁的地方一节下的单元文档中有记录。

这意味着如果在模块module中使用from a import b,就必须在module中修补b的引用,例如修补module.b而不是a.b。如果您使用patch.object,这意味着使用patch.object(module, "b")而不是patch.object(a, "b")

在您的情况下,您应该使用如下内容:

代码语言:javascript
复制
from patch_mongo import student_dao

class TestStudent:

    def test_student(self, patch_mongo):
        with patch.object(student_dao, "mongo_connection", patch_mongo):
            student = student_dao.StudentDAO()
            ...

请注意,出于类似的原因,我也更改了StudentDAO的导入。使用您的代码,您可以在测试模块中创建另一个StudentDAO引用,它有自己的mongo_connection引用。

还请注意,您的测试是不工作的(您从来没有设置学生数据),但我想这是由于降低了代码。

其他一些有用的链接:

顺便说一句:在很多这样的答案(包括我自己的答案)中都提到过这一点,而且我通常不会添加其他答案。这些问题的问题是总结,任何寻找类似问题的人都找不到。然而,你的问题摘要确实显示了问题所在,希望你能更容易地发现.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73393474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档