从 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" 现在可以正常工作了。