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

如何用unittest Mock全局方法?测试为何报项目未找到错误?

问题背景

这是一个非常简单的示例:

# my_func.py

from google.cloud import storage

storage_client = storage.Client()

def one():
    return 1



# my_func_test.py

import unittest
from my_func import one, storage
from unittest import mock

class TestOne(unittest.TestCase):
    @ mock.patch('my_func.storage')
    def test_assert(self, mock_storage):
        mock_bucket = mock.Mock()
        mock_storage.Client.return_value = mock_bucket
        result = one()
        self.assertEqual(result, 1)

unittest.main()

运行该测试时返回“Project was not passed and could not be determined from the environment”错误,但将storage_client放入one()函数内则测试全部通过,请问这是为什么?


原因解析

核心问题是模块导入时机和mock生效时机不匹配:

  • 全局作用域代码的执行时机:Python模块在被导入时,会立即执行所有全局作用域的代码。你在my_func.py里把storage_client = storage.Client()写在函数外面,当测试模块执行from my_func import one, storage时,这行代码就会被触发,调用真实的storage.Client()构造函数。而你的@mock.patch('my_func.storage')是在测试函数运行时才生效的,这时候真实的Client已经初始化过了,mock根本没覆盖到这次调用,自然会触发真实Client的校验逻辑,要求提供项目信息,导致报错。

  • 函数内部代码的执行时机:如果把storage_client = storage.Client()移到one()函数内部,这行代码只会在调用one()的时候才执行。测试函数里先完成了mock的设置,再调用one(),此时storage.Client()已经被mock替换,不会触发真实的初始化逻辑,也就不会报错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:32:52