Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django测试-所有测试中的补丁对象_Python_Django_Unit Testing_Django Testing_Python Mock - Fatal编程技术网

Python Django测试-所有测试中的补丁对象

Python Django测试-所有测试中的补丁对象,python,django,unit-testing,django-testing,python-mock,Python,Django,Unit Testing,Django Testing,Python Mock,我需要为我的测试创建某种类型的MockMixin。它应该包括所有调用外部源的模拟。 例如,每次我在管理面板中保存模型时,我都会调用一些远程URL。这将是很好的,有嘲笑和使用这样: class ExampleTestCase(MockedTestCase): # tests 所以每次我在admin中保存模型时,例如在功能测试中,都会应用这个模拟,而不是调用远程URL 这真的有可能吗?我能在一个特定的测试中做到这一点,这不是问题。但是,有一些全局模拟会更有用,因为我经常使用它。根据: 补丁

我需要为我的测试创建某种类型的
MockMixin
。它应该包括所有调用外部源的模拟。 例如,每次我在管理面板中保存模型时,我都会调用一些远程URL。这将是很好的,有嘲笑和使用这样:

class ExampleTestCase(MockedTestCase):
    # tests
所以每次我在admin中保存模型时,例如在功能测试中,都会应用这个模拟,而不是调用远程URL

这真的有可能吗?我能在一个特定的测试中做到这一点,这不是问题。但是,有一些全局模拟会更有用,因为我经常使用它。

根据:

补丁可以用作TestCase类装饰器。它的工作原理是 修饰类中的每个测试方法。这减少了样板文件 当您的测试方法共享公共补丁集时编写代码

这基本上意味着您可以创建一个应用了
@patch
decorator的基本测试类,该类将模拟外部调用,而内部的每个测试方法都将被执行

此外,您还可以分别在
setUp()
tearDown()
方法中使用patcher的方法:

class BaseTestCase(TestCase):
    def setUp(self):
        self.patcher = patch('mymodule.foo')
        self.mock_foo = self.patcher.start()

    def tearDown(self):
        self.patcher.stop()
如果您使用的是
teardown()
,那么

您必须通过调用
stop
确保修补“撤消”。这可能比您想象的更加烦躁,因为如果在
设置中引发异常
,则不会调用
拆卸

如果测试中出现异常,则修补不会撤消。更好的方法是在
设置()中调用。然后您可以完全省略
tearDown()
方法

class BaseTestCase(TestCase):
    def setUp(self):
        self.patcher = patch('mymodule.foo')
        self.mock_foo = self.patcher.start()
        self.addCleanup(self.patcher.stop) # add this line

我最终创造了一个测试跑步者来达到我的目的。我需要模拟文件存储,以便在测试时图像不会实际写入文件系统。images对象在许多测试中都被调用,因此修补每个类将不会
DRY
。此外,我注意到,如果测试失败,模拟文件本身会将其留在系统上。但这种方法没有

我在项目根目录中创建了一个文件
runner.py

#runner.py
从unittest.mock导入修补程序
从django.test.runner导入DiscoveryRunner
从myapp.Factorys导入ImageFactory
类UnitTestRunner(DiscoveryRunner):
@修补程序('django.core.files.storage.FileSystemStorage.save')
def运行测试(自我、测试标签、模拟保存、额外测试=无,**kwargs):
mock_save.return_value=ImageFactory.get_image()
return super().运行测试(测试标签,额外测试=None,**kwargs)
然后,我将使用
python manage.py测试运行测试--testrunner=runner.UnitTestRunner


为了清晰起见,
ImageFactory.get\u image
方法是一种自定义方法

从django.core.files.base导入内容文件
从factory.django导入DjangoModelFactory
从io导入字节io
从PIL将图像导入为PIL图像
从随机导入randint
类ImageFactory(DjangoModelFactory):
@类方法
def get_图像(cls,name='trial',extension='png',size=None):
如果大小为“无”:
宽度=randint(20,1000)
高度=randint(20,1000)
大小=(宽度、高度)
颜色=(256,0,0)
file_obj=BytesIO()
image=pilmimage.new(“RGBA”,size=size,color=color)
image.save(文件\对象,扩展名)
文件_obj.seek(0)
返回ContentFile(file_obj.read(),f'{name}.{extension}')

这也意味着我必须装饰我的每个测试用例,而不是
Mixin
测试类。我不得不为每个测试方法添加额外的参数,这也很不方便。但总比什么都没有好。@galozek请看相关主题:和。第二个解决方案奏效了。我尝试了这种方法,但缺少
start()
/
stop()
部分。谢谢。请注意,您最好使用
self.addCleanup(self.patcher.stop)
而不是在
tearDown
中执行此操作,因为无论是否存在异常,清理都会运行。请参阅@Meistro的答案。不要忘记包括导入:
来自unittest导入测试用例
来自导入unittest。模拟导入补丁
将始终被调用,即使您的测试引发异常。从文档中可以看到:“如果安装()失败,意味着拆卸()因此,调用
addCleanup
比希望在
设置中不出现异常要好。不要忘记包括导入:
来自unittest导入TestCase
来自import unittest.mock导入补丁
wrt@Meistro上面提到的内容。。。确保尽快在
设置
方法中添加清理钩子,否则,如果在添加钩子之前失败,它将无效