tun*_*rob 25 python django unit-testing django-testing python-mock
我需要MockMixin为我的测试创建一些.它应该包括调用外部源的所有内容的模拟.例如,每次我在管理面板中保存模型时,我都会调用一些远程URL.如果嘲笑并使用那样的话会很好:
class ExampleTestCase(MockedTestCase):
# tests
Run Code Online (Sandbox Code Playgroud)
因此,每次我在管理员中保存模型时,例如在功能测试中,应用此模拟而不是调用远程URL.
这有可能吗?我能够为1个特定测试做到这一点,这不是问题.但是有一些全局模拟更有用,因为我经常使用它.
ale*_*cxe 41
根据mock文件:
Patch可以用作TestCase类装饰器.它通过装饰类中的每个测试方法来工作.当您的测试方法共享一个公共的补丁集时,这会减少样板代码.
这基本上意味着您可以创建一个基础测试类,其上@patch应用了装饰器,可以模拟外部调用,同时执行内部的每个测试方法.
此外,您可以分别使用start()和stop() patcher的方法setUp()和tearDown()方法:
class BaseTestCase(TestCase):
def setUp(self):
self.patcher = patch('mymodule.foo')
self.mock_foo = self.patcher.start()
def tearDown(self):
self.patcher.stop()
Run Code Online (Sandbox Code Playgroud)
Mei*_*tro 22
只是为了增加alecxe的答案,如果你正在使用teardown()那么根据文档
您必须通过调用确保修补"撤消"
stop.这可能比您想象的更为繁琐,因为如果在setUp那时引发异常tearDown则不会被调用.
如果您的测试中出现异常,则您的修补程序将无法撤消.更好的方法是打电话给addCleanup()你setUp().然后你可以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
Run Code Online (Sandbox Code Playgroud)
我最终创建了一个测试运行程序来实现我的目的。我需要模拟文件存储,以便在测试时图像不会实际写入文件系统。在许多测试中都会调用图像对象,因此不会修补每个类DRY。另外,我注意到模拟文件本身会将其保留在系统上,以防测试失败。但这个方法却没有。
runner.py我在项目根目录中创建了一个文件
# runner.py
from unittest.mock import patch
from django.test.runner import DiscoverRunner
from myapp.factories import ImageFactory
class UnitTestRunner(DiscoverRunner):
@patch('django.core.files.storage.FileSystemStorage.save')
def run_tests(self, test_labels, mock_save, extra_tests=None, **kwargs):
mock_save.return_value = ImageFactory.get_image()
return super().run_tests(test_labels, extra_tests=None, **kwargs)
Run Code Online (Sandbox Code Playgroud)
然后我会使用运行我的测试python manage.py tests --testrunner=runner.UnitTestRunner
为了清楚起见,该ImageFactory.get_image方法是自定义方法
from django.core.files.base import ContentFile
from factory.django import DjangoModelFactory
from io import BytesIO
from PIL import Image as PilImage
from random import randint
class ImageFactory(DjangoModelFactory):
@classmethod
def get_image(cls, name='trial', extension='png', size=None):
if size is None:
width = randint(20, 1000)
height = randint(20, 1000)
size = (width, height)
color = (256, 0, 0)
file_obj = BytesIO()
image = PilImage.new("RGBA", size=size, color=color)
image.save(file_obj, extension)
file_obj.seek(0)
return ContentFile(file_obj.read(), f'{name}.{extension}')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11785 次 |
| 最近记录: |