You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用unittest模拟嵌套构造函数中的table.get_item调用?

解决DynamoDB get_item模拟失败的问题

你的测试失败核心原因是mock的目标路径不对,再加上测试代码里真实实例初始化和mock逻辑冲突。下面一步步帮你修正:

问题拆解

  1. 你现在mock的是src.DBOps这个自定义类,但实际上需要模拟的是boto3创建的DynamoDB Table实例的get_item方法——毕竟你的业务类是调用boto3的资源来操作数据库的。
  2. setUp里初始化了真实的dynamodbOps实例,这会触发真实的boto3资源初始化逻辑,和测试中的mock完全冲突,相当于一边模拟一边调用真实服务,肯定会失败。

修正方案

方案1:模拟boto3资源链(推荐)

我们从boto3的资源创建环节开始mock,让它返回预设的模拟Table实例:

import unittest
from unittest import mock
from src.DBOps import DBOps

class test_GetDBItem(unittest.TestCase):
    @mock.patch('src.DBOps.boto3.resource')
    def test_run_query_with_item(self, mock_boto3_resource):
        # 1. 模拟Table实例的get_item方法返回值
        mock_table = mock.Mock()
        mock_table.get_item.return_value = {"Blah": "Blah Blah"}
        
        # 2. 让boto3.resource返回的dynamodb实例,能得到我们模拟的Table
        mock_dynamodb = mock.Mock()
        mock_dynamodb.Table.return_value = mock_table
        mock_boto3_resource.return_value = mock_dynamodb
        
        # 3. 初始化业务类(此时用的都是模拟资源)
        db_table = "test_table"
        db_ops = DBOps()
        dyn = db_ops.dynamodbOps(db_table)
        
        # 4. 执行测试并验证
        pool = 'some_pool'
        response = dyn.GetDBItem(pool)
        
        mock_table.get_item.assert_called_once_with(Key={'pool': pool})
        self.assertEqual(response, {"Blah": "Blah Blah"})

方案2:直接mock目标方法

如果想更精准地mock table.get_item,可以指定正确的mock路径(路径要和被测试代码里的导入层级对应):

import unittest
from unittest import mock
from src.DBOps import DBOps

class test_GetDBItem(unittest.TestCase):
    @mock.patch('src.DBOps.DBOps.dynamodbOps.table.get_item')
    def test_run_query_with_item(self, mock_get_item):
        mock_get_item.return_value = {"Blah": "Blah Blah"}
        
        # 初始化业务类
        db_table = "test_table"
        db_ops = DBOps()
        dyn = db_ops.dynamodbOps(db_table)
        
        # 执行测试
        pool = 'some_pool'
        response = dyn.GetDBItem(pool)
        
        # 验证调用
        mock_get_item.assert_called_once_with(Key={'pool': pool})
        self.assertEqual(response, {"Blah": "Blah Blah"})

额外必须修正的点

你的GetDBItem方法没有返回值!当前代码里response = self.table.get_item(...)后没有return response,所以测试中拿到的response会是None,记得在原业务代码里补充这一行:

def GetDBItem(self,pool):
    response = self.table.get_item(Key={'pool' : pool})
    return response  # 补充返回值,否则测试永远拿不到预期结果

内容的提问来源于stack exchange,提问作者Sagar Kadambi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 17:37:40