如何在测试函数中用任意函数替换方法(不使用patch.object)



我的尝试是模拟具有预定义值的函数中的数据库操作。

我修补了 mongo 集合实例的 find 方法,并将字典列表设置为演示返回值(find或多或少地返回类似的数据结构(。但问题是,find返回具有count()方法的东西,该方法不需要参数,而我设置的返回值(list(也有一个count()方法,但它需要一个参数,它的目的也不同。

因此,我的目标是更改count()的行为,以便它返回我硬编码的列表的len。(find方法的返回值的len(

下面是代码:

some_module.py,

def somefunc():
    items = mongo_collection.find({"some_field": True}).batch_size(50)
    if items.count() > 0:
        counter += 1

test_some_module.py,

@patch.object(some_module, 'mongo_collection')
def test_some_func(patched_collection):
    patched_collection.find.return_value.batch_size.return_value = 
                                              [{'id': 1}, {'id': 2}]
    patched_collection.find.return_value.batch_size.return_value.count = ?

目前尚不清楚您要测试的内容。

如果出于某种原因你想要类似列表的"响应"并且它应该充当响应(即count方法(,你应该创建这样的对象并将其设置为返回值。

现在您设置[{'id': 1}, {'id': 2}] .一旦你通过mongo_collection.find().batch_size()返回这个列表,结果实际上是一个列表,而不是模拟。因此,没有其他类似.count = ...的东西可用。

因此,有一些方法可以:

  1. 测试响应正文和您在不同测试中的计数,修补连接器的方式不同
  2. 创建更好的响应模拟,即

    class Response(list):
        def count(self):
            return len(self)
    ...
    patched_collection.find.return_value.batch_size.return_value = Response([{'id': 1}, {'id': 2}])
    
  3. 创建响应模拟
  4. 作为模拟库响应的实例

最新更新