我有一个 utils 类,除了其他东西之外,它还有一个获取 id 的函数:
# utils.py
def get_id():
return ...
另外,还有另一个类,比如说关于汽车的类,它使用这个函数:
# car.py
from utils import get_id
class Car:
...
def setup(self):
self.id = get_id()
我想运行一个应该提供特定ID的单元测试,这就是我嘲笑这个函数的原因:
# test_car.py
import unittest
from unittest.Mock import Mock
import utils
class TestCar(unittest.TestCase):
...
def test_car_setup(self):
utils.get_id = Mock(callable, return_value="my-testing-id")
car = Car()
car.setup()
...
但是这个模拟不起作用。我仍然得到原始函数的行为。 但是,我可以通过像这样调整汽车类别来使其工作:
# car.py
from . import utils
class Car:
...
def setup(self):
self.id = utils.get_id()
现在的问题是,为什么它可以工作,而以前的版本却不能? 我最初认为这可能是按引用调用/按值调用问题,但调试器显示现在无论我如何调整导入,utils 函数始终是同一个对象。
我知道这可能不是一个典型的问题,因为我的项目正在运行,但我无法理解导致它的Python的工作原理,如果有人能启发我,我将不胜感激。
提前致谢!
test_car.py
对您的文件
test_car.py
进行一些更改就足够了,而car.py
和utils.py
保持不变;文件car.py
与原始from utils import get_id
如下所示:
# car.py
from utils import get_id
class Car:
...
def setup(self):
self.id = get_id()
下面我向您展示文件
test_car.py
#test_car.py
import unittest
from unittest.mock import Mock
#import utils # <----- this import is now useless
from car import Car # <----- add this import
import car as module_car # <----- add this import (added name module_car
# to avoid name collision)
class TestCar(unittest.TestCase):
def test_car_setup(self):
# I have commented your instruction
#utils.get_id = Mock(callable, return_value="my-testing-id")
# USE THIS INSTRUCTION
module_car.get_id = Mock(callable, return_value="my-testing-id")
car = Car()
car.setup()
if __name__ == '__main__':
unittest.main()
所需的更改如下:
utils.get_id = Mock(callable, return_value="my-testing-id") ---> module_car.get_id = Mock(callable, return_value="my-testing-id")
指令
module_car.get_id = Mock(...)
替换模块内部使用的名称get_id
所指向的对象car.py
。
您的指令 (
utils.get_id = Mock(...)
) 替换了文件 get_id
中名称 utils.py
指向的对象,但方法 setup()
使用的对象是由 get_id
内部定义的名称 car.py
指向的。