首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用假mongoDB进行脓毒物检测

使用假mongoDB进行脓毒物检测
EN

Stack Overflow用户
提问于 2018-08-23 14:36:54
回答 1查看 16K关注 0票数 10

我有连接到MongoDB客户端的代码,我正在尝试测试它。对于测试,我不想连接到实际的客户端,所以我试图找出一个假的测试目的。代码的基本流程是,我有一个函数,在某个地方创建一个pymongo客户端,然后查询这个函数,然后生成一个用于其他地方的dict。

我想使用pytest编写一些测试,这些测试将测试不同的函数和调用get_stuff的类。我的问题是get_stuff调用mongo(),这实际上是连接到数据库的原因。我只是想用pytest.fixture(autouse=True)mongomock.MongoClient()来代替mongo()

但这并不能取代mongo_stuff.mongo()。我是否可以告诉pytest替换一个函数,从而调用fixture而不是实际的函数?我认为,使fixture比实际模块中的函数在命名空间中使我的测试mongo()具有更高的优先级。

下面是我的示例文件结构:

代码语言:javascript
复制
.
├── project
│   ├── __init__.py
│   ├── mongo_stuff
│   │   ├── __init__.py
│   │   └── mongo_stuff.py
│   └── working_class
│       ├── __init__.py
│       └── somewhere_else.py
└── testing
    ├── __init__.py
    └── test_stuff.py

mongo_stuff.py

代码语言:javascript
复制
import pymongo

def mongo():
    return pymongo.MongoClient(connection_params)

def get_stuff():
    db = mongo()  # Makes the connection using another function
    stuff = query_function(db)  # Does the query and makes a dict
    return result

somewhere_else.py

代码语言:javascript
复制
from project.mongo_stuff import mongo_stuff

mongo_dict = mongo_stuff.get_stuff()

test_stuff.py

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

@pytest.fixture(autouse=True)
def patch_mongo(monkeypatch):
    db = mongomock.MongoClient()
    def fake_mongo():
        return db
    monkeypatch.setattr('project.mongo_stuff.mongo', fake_mongo)

from poject.working_class import working_class  # This starts by calling project.mongo_stuff.mongo_stuff.get_stuff()

这将给我一个连接错误,因为mongo_stuff.py中的connection params只能在生产环境中工作。如果我将来自test_stuff.pyimport语句放入测试函数中,那么它可以正常工作,mongomock db将在测试环境中使用。我还尝试将setattr更改为monkeypatch.setattr('project.working_class.mongo_stuff.mongo', fake_mongo),这也不起作用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-23 21:12:53

您已经完成了一半:您已经为db客户机创建了一个模拟,现在您必须修补mongo_stuff.mongo函数来返回模拟,而不是真正的连接:

代码语言:javascript
复制
@pytest.fixture(autouse=True)
def patch_mongo(monkeypatch):
    db = mongomock.MongoClient()
    def fake_mongo():
        return db
    monkeypatch.setattr('mongo_stuff.mongo', fake_mongo)

编辑:

获得连接错误的原因是您在test_stuff中在模块级别导入了test_stuff,而somewhere_else也在模块级别上运行连接代码。因此,修补固定装置将来得太晚,将不会有任何影响。如果要在模块级别导入,则必须在导入somewhere_else之前对mongo客户端进行修补。这将避免错误的产生,但非常丑陋:

代码语言:javascript
复制
from project.mongo_stuff import mongo_stuff
import mongomock
import pytest

from unittest.mock import patch

with patch.object(mongo_stuff, 'mongo', return_value=mongomock.MongoClient()):

    from project.working_class import somewhere_else


@patch.object(mongo_stuff, 'mongo', return_value=mongomock.MongoClient())
def test_db1(mocked_mongo):
    mongo_stuff.mongo()
    assert True


@patch.object(mongo_stuff, 'mongo', return_value=mongomock.MongoClient())
def test_db2(mocked_mongo):
    somewhere_else.foo()
    assert True

如果可能,您应该避免在模块级别上运行代码,或者在测试中运行在模块级别上执行代码的导入(正如您在注释中已经发现的那样)。

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

https://stackoverflow.com/questions/51988331

复制
相关文章

相似问题

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