【问题标题】:How do I patch a python method for a test case to run?如何修补 python 方法以运行测试用例?
【发布时间】:2018-06-08 19:08:20
【问题描述】:

我正在进行的一个项目基本上使用 django 来完成所有工作。在编写模型时,我发现有必要重写 save() 方法来分拆一个由工作人员运行的任务:

class MyModel(models.Model)
    def _start_processing(self):
        my_task.apply_async(args=['arg1', ..., 'argn'])
    def save(self, *args, **kwargs):
        """Saves the model object to the database"""
        # do some stuff
        self._start_processing()
        # do some more stuff
        super(MyModel, self).save(*args, **kwargs)

在我的测试器中,我想测试由# do some stuff# do some more stuff 指定的保存覆盖部分,但不想运行该任务。为此,我相信我应该使用模拟(我很陌生)。

在我的测试类中,我已将其设置为跳过任务调用:

class MyModelTests(TestCase):
    def setUp(self):
        # Mock the _start_processing() method. Ha!
        @patch('my_app.models.MyModel._start_processing')
        def start_processing(self, mock_start_processing):
            print('This is when the task would normally be run, but this is a test!')

        # Create a model to test with
        self.test_object = MyModelFactory()

由于工厂创建并保存了模型的实例,我需要在调用之前覆盖_start_processing() 方法。以上似乎不起作用(并且任务运行并失败)。我错过了什么?

【问题讨论】:

    标签: python django unit-testing mocking


    【解决方案1】:

    首先,您必须将装饰器包装到装饰器中,而不是要用作替换的功能,而是模拟应该在其中工作的“范围”。因此,例如,如果您需要为整个 MyModelTests 类模拟 _start_processing,您应该将装饰器放在类定义之前。如果只针对一种测试方法 - 只用它包装测试方法。

    其次,在类之外的某个地方定义start_processing 函数,并传递@patch('my_app.models.MyModel._start_processing', new=start_processing),这样它就会知道用什么来代替实际方法。但要注意匹配实际的方法签名,所以只使用

    def start_processing(self):
        print('This is when the task would normally be run, but this is a test!')
    

    第三,你必须在这个类中的每个测试用例中添加mock_start_processing 参数(test_...方法),因为模拟是这样工作的:)。

    最后。您必须注意您正在修补的target。您当前的my_app.models.MyModel._start_processing 可能已损坏。您必须使用它被使用的路径来修补类,而不是它被定义的路径。因此,如果您在TestCase 中创建带有MyModelFactory 的对象,并且MyModelFactory 位于my_app.factories 中,并且它将MyModel 导入为from .models import MyModel,您将不得不使用@patch('my_app.factories.MyModel._start_processing'),而不是'my_app.models.MyModel._start_processing'

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多