在 python unittest 中模拟实例方法

问题描述 投票:0回答:1

我是一名软件开发人员多年,但对 Python 还很陌生。我正在编写一个单元测试(因此不存在数据库连接),该测试涉及 Django 中的一个模型,该模型访问通过外键连接引用的另一个模型。我想模拟访问此连接的方法,并将结果替换为硬编码响应,但每个实例的响应都是不同的。

这是一个最小的例子:

### tests/test_MyTestCase.py

from unittest import TestCase
from djangoapi.models import *


class MyTestCase(TestCase):
    def setUp(self):
        self.instance1 = MyModel()
        self.instance2 = MyModel()

        foreignKey1 = MySubModel()
        foreignKey1.my_value = 1

        # Mock that self.instance1.submodel_set.all() returns [foreignKey1]
        
        foreignKey2 = MySubModel()
        foreignKey2.my_value = 2

        # Mock that self.instance2.submodel_set.all() returns [foreignKey2]

    def testSomething(self):
        self.assertEqual(self.instance1.get_max_value(), 1)
        self.assertEqual(self.instance2.get_max_value(), 2)

        
### models.py

from django.db import models

class MyModel(models.Model):
    def get_max_value(self):
        value = 0
        # the return value of self.submodel_set.all() is what I want to mock
        for model in self.submodel_set.all():
            value = max(value, model.my_value)
        return value


class Submodel(models.Model):
    my_model = models.ForeignKey(MyModel, null=True, on_delete=models.SET_NULL)
    my_value = models.IntegerField()

我尝试了

the @patch decorator
Mock()
MagicMock()
的几种组合,但无法使其工作。预先感谢您!

python python-3.x django django-rest-framework python-unittest
1个回答
0
投票

经过更多研究,我发现主要问题是模拟不能在

setUp
方法中发生,而必须在测试方法本身中完成。这意味着一些代码重复,但至少现在可以工作了。作为参考,这是工作示例:

from unittest import TestCase
from unittest.mock import patch
from djangoapi.models import *


class MyTestCase(TestCase):
    def setUp(self):
        self.my_model = MyModel()

        self.foreignKey1 = MySubModel()
        self.foreignKey1.my_value = 1

        self.foreignKey2 = MySubModel()
        self.foreignKey2.my_value = 2

    @patch('djangoapi.models.MyModel.submodel_set')
    def testSomething(self, mock_submodel_set):
        mock_submodel_set.all.return_value = [self.foreignKey1]
        self.assertEqual(self.my_model.get_max_value(), 1)

        mock_submodel_set.all.return_value = [self.foreignKey2]
        self.assertEqual(self.my_model.get_max_value(), 2)
© www.soinside.com 2019 - 2024. All rights reserved.