如何在python中为所有测试全局模拟方法

Jam*_*rdy 6 python django unit-testing mocking

我的Django项目在许多应用程序的各个模块中进行了数百项测试。最近,我们添加了一项功能,该功能可在创建User对象(使用Django Signals)时(通过sendgrid)发送电子邮件。

我们遇到的问题是,在运行测试时,许多用户都是显式创建的或作为固定的。这导致在每个测试周期发送数百封电子邮件,并且由于其中大多数无效,因此我们会收到数百封退信。除了所涉及的费用外,Sendgrid实际上还因行为异常而暂停了我们的帐户。

显然,我可以单独模拟每个测试的调用,但是这必须在数百个地方进行,并且我们必须记住在以后创建的所有测试中都进行调用。

是否有一种更简单的方法来全局模拟所有测试的特定代码块(当然,在实际运行时保持完整)

dja*_*aut 7

我在大型 django 项目中使用的两种方法

假设:my_mock = patch("myapp.mymodule.MyClass.my_method")

1)您可以在自定义测试运行器类中添加模拟:

from mock import patch
from django.test.runner import DiscoverRunner

class MyTestRunner(DiscoverRunner):
    @my_mock
    def run_tests(self, test_labels, **kwargs):
         return super(MyTestRunner, self).run_tests(test_labels, **kwargs)
Run Code Online (Sandbox Code Playgroud)

2) 您可以在自定义基测试类上添加模拟:

from mock import patch
from django.test import TestCase

class MyTestCase(TestCase):

   def setUp(self):
      super(MyTestCase, self).setUp()
      my_mock.start()

   def tearDown(self):
      super(MyTestCase, self).tearDown()
      my_mock.stop()
Run Code Online (Sandbox Code Playgroud)


Mic*_*ico 5

我不使用 Django,也许有一些惯用的方法可以在 Django 中做得很好。

我对这类问题的方法是创建自己的TestCase类,从延伸unittest.TestCase和覆盖setUpClass()/ tearDownClass/ setUp()/tearDown()设置模拟/补丁,我需要全球在我的测试(或至少其中的一部分)。

现在每次我需要它而不是导入unittest.TestCase我正在导入的模块myunittest.TestCase

例子: myunittest.py

import unittest

class TestCase(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        super(TestCase, cls).setUpClass()
        # Init your class Mock/Patch

    @classmethod
    def tearDownClass(cls):
        # Remove Mocks or clean your singletons
        super(TestCase, cls).tearDownClass()

    def setUp(self):
        super(TestCase, self).setUp()
        # Init your obj Mock/Patch

    @classmethod
    def tearDown(self):
        # ... if you need it
        super(TestCase, self).tearDown()
Run Code Online (Sandbox Code Playgroud)

在你的测试中:

from myunittest import TestCase

    class Test(TestCase):
        ... Your test
Run Code Online (Sandbox Code Playgroud)