从 2 个不同的文件中模拟 2 类
mocking 2 classes from 2 different files
我有一个 class 模拟的例子:
worker.py
import os
class Helper:
def __init__(self, path):
self.path = path
def get_folder(self):
base_path = os.getcwd()
return os.path.join(base_path, self.path)
def get_path(self):
return self.path
class Worker:
def __init__(self):
self.helper = Helper('db')
def work(self):
path = self.helper.get_path()
print(f'Working on {path}')
return path
还有一个测试文件:test_worker.py
from unittest import TestCase, mock
from worker import Worker, Helper
class TestWorkerModule(TestCase):
def test_patching_class(self):
with mock.patch('worker.Helper') as MockHelper:
MockHelper.return_value.get_path.return_value = 'testing'
worker = Worker()
self.assertEqual(worker.work(), 'testing')
测试 returns 可以,只要 2 classes 在同一个文件中。将它们分成 2 个文件 worker_1.py for class Helper 和 worker_2.py for class Worker,测试失败:
AssertionError: 'db' != 'testing'
为什么?我该如何纠正这种行为?
谢谢
假设我们有两个文件,worker.py 和 helper.py
worker.py:
from helper import Helper
class Worker:
def __init__(self):
self.helper = Helper('db')
def work(self):
path = self.helper.get_path()
print('Working on {path}')
return path
helper.py:
import os
class Helper:
def __init__(self, path):
self.path = path
def get_folder(self):
base_path = os.getcwd()
return os.path.join(base_path, self.path)
def get_path(self):
return self.path
你在这里所做的是将 Helper class 导入 worker 模块,
所以当你在测试中尝试这样做时_worker.py:
from unittest import TestCase, mock
from worker import Worker
class TestWorkerModule(TestCase):
def test_patching_class(self):
with mock.patch('helper.Helper') as MockHelper:
MockHelper.return_value.get_path.return_value = 'testing'
worker = Worker()
self.assertEqual(worker.work(), 'testing')
结果:
AssertionError: 'db' != 'testing'
- db
+ testing
您正在修补 helper.py 模块中的助手 class,
但是您已经将 Helper class 导入到 worker 模块中,因此您需要在 worker 模块中修补 Helper class,例如:
from unittest import TestCase, mock
from worker import Worker
class TestWorkerModule(TestCase):
def test_patching_class(self):
with mock.patch('worker.Helper') as MockHelper:
MockHelper.return_value.get_path.return_value = 'testing'
worker = Worker()
self.assertEqual(worker.work(), 'testing')
结果:
Ran 1 test in 0.002s
OK
另一种让它适用于一般用例的方法(假设你想在所有使用它的模块中修补 Helper class),它是将 worker.py 更改为:
import helper
class Worker:
def __init__(self):
self.helper = helper.Helper('db')
def work(self):
path = self.helper.get_path()
print('Working on {path}')
return path
这里导入了helper模块,使用helper模块下的Helperclass,
所以现在你的 test.py 应该是这样的:
from unittest import TestCase, mock
from worker import Worker
class TestWorkerModule(TestCase):
def test_patching_class(self):
with mock.patch('helper.Helper') as MockHelper:
MockHelper.return_value.get_path.return_value = 'testing'
worker = Worker()
self.assertEqual(worker.work(), 'testing')
结果:
Ran 1 test in 0.001s
OK
这是可行的,因为我们没有将助手 class 导入工作模块,而是导入了助手模块,因此修补 "helper.Helper" 现在可以正常工作了。
我有一个 class 模拟的例子:
worker.py
import os
class Helper:
def __init__(self, path):
self.path = path
def get_folder(self):
base_path = os.getcwd()
return os.path.join(base_path, self.path)
def get_path(self):
return self.path
class Worker:
def __init__(self):
self.helper = Helper('db')
def work(self):
path = self.helper.get_path()
print(f'Working on {path}')
return path
还有一个测试文件:test_worker.py
from unittest import TestCase, mock
from worker import Worker, Helper
class TestWorkerModule(TestCase):
def test_patching_class(self):
with mock.patch('worker.Helper') as MockHelper:
MockHelper.return_value.get_path.return_value = 'testing'
worker = Worker()
self.assertEqual(worker.work(), 'testing')
测试 returns 可以,只要 2 classes 在同一个文件中。将它们分成 2 个文件 worker_1.py for class Helper 和 worker_2.py for class Worker,测试失败:
AssertionError: 'db' != 'testing'
为什么?我该如何纠正这种行为?
谢谢
假设我们有两个文件,worker.py 和 helper.py
worker.py:
from helper import Helper
class Worker:
def __init__(self):
self.helper = Helper('db')
def work(self):
path = self.helper.get_path()
print('Working on {path}')
return path
helper.py:
import os
class Helper:
def __init__(self, path):
self.path = path
def get_folder(self):
base_path = os.getcwd()
return os.path.join(base_path, self.path)
def get_path(self):
return self.path
你在这里所做的是将 Helper class 导入 worker 模块, 所以当你在测试中尝试这样做时_worker.py:
from unittest import TestCase, mock
from worker import Worker
class TestWorkerModule(TestCase):
def test_patching_class(self):
with mock.patch('helper.Helper') as MockHelper:
MockHelper.return_value.get_path.return_value = 'testing'
worker = Worker()
self.assertEqual(worker.work(), 'testing')
结果:
AssertionError: 'db' != 'testing'
- db
+ testing
您正在修补 helper.py 模块中的助手 class, 但是您已经将 Helper class 导入到 worker 模块中,因此您需要在 worker 模块中修补 Helper class,例如:
from unittest import TestCase, mock
from worker import Worker
class TestWorkerModule(TestCase):
def test_patching_class(self):
with mock.patch('worker.Helper') as MockHelper:
MockHelper.return_value.get_path.return_value = 'testing'
worker = Worker()
self.assertEqual(worker.work(), 'testing')
结果:
Ran 1 test in 0.002s
OK
另一种让它适用于一般用例的方法(假设你想在所有使用它的模块中修补 Helper class),它是将 worker.py 更改为:
import helper
class Worker:
def __init__(self):
self.helper = helper.Helper('db')
def work(self):
path = self.helper.get_path()
print('Working on {path}')
return path
这里导入了helper模块,使用helper模块下的Helperclass, 所以现在你的 test.py 应该是这样的:
from unittest import TestCase, mock
from worker import Worker
class TestWorkerModule(TestCase):
def test_patching_class(self):
with mock.patch('helper.Helper') as MockHelper:
MockHelper.return_value.get_path.return_value = 'testing'
worker = Worker()
self.assertEqual(worker.work(), 'testing')
结果:
Ran 1 test in 0.001s
OK
这是可行的,因为我们没有将助手 class 导入工作模块,而是导入了助手模块,因此修补 "helper.Helper" 现在可以正常工作了。