【问题标题】:django: mock post_save signal handler?django:模拟 post_save 信号处理程序?
【发布时间】:2017-03-20 20:49:16
【问题描述】:

tests.py

from unittest.mock import patch

from orders.models import Order

class OrderModelTest(CartSetupTestCase):

    def test_string_representation(self):
        # Mocking Order's post_save signal
        with patch('orders.signals.post_save_order', autospec=True) as mocked_handler:
            post_save.connect(
                mocked_handler,
                sender=Order,
                dispatch_uid='test_cache_mocked_handler'
            )
            order = Order.objects.create(
                user=self.user,
                merchant_uid="1475633246629",
                customer_name="asd",
                address="주소",
                address_detail="asdfdsa",
                postal_code="12345",
                phone_number="01095104344",
                possible_date_start="2011-11-24",
                possible_date_end="2011-11-24",
                possible_time_start="11:22 AM",
                possible_time_end="11:22 AM",
                total_price=self.cart.total_price,
            )

signals.py

@receiver(post_save, sender=Order, dispatch_uid="spacegraphy")
def post_save_order(sender, instance, created, **kwargs):
    if created:
        SlackNotification.objects.create(
            receiver="order_web",
            content="asdfasdf"
        )

我关注了https://stackoverflow.com/a/13119150/3595632,但它不起作用,这意味着它实际上调用了信号处理程序! (我使用print() 进行了检查)

有什么问题吗?

【问题讨论】:

  • 为什么不直接在你的测试中调用这个函数呢?考虑到它是核心 django,测试在创建某些东西时触发信号有点多。您也可以使用适当的签名调用signal.send 方法。
  • @theWanderer4865 我没听懂你说什么。请给我一个例子好吗?
  • 你断言 mock_handler 被调用了吗?当您的信号代码被导入时(当 Django 启动时),它将向信号注册任意数量的处理程序 - 如果您不希望其他处理程序运行,您应该显式断开它。还有更多要说的,但这将是第 1 步。

标签: django mocking django-testing


【解决方案1】:

FWIW 我也遵循同样的方法,但需要模拟 celery 的 send_task。通读后,我确实认识到,信号是有价值的,不应该被嘲笑(这是一个期望的动作,对吧?),所以解决方案是模拟发生在 inside信号(与外部服务的通信)。总而言之,我会建议:

from unittest.mock import patch
from orders.models import Order

class OrderModelTest(CartSetupTestCase):

    @patch('orders.signals.SlackNotification.objects.create')
    def test_string_representation(self, create):
        order = Order.objects.create(
            user=self.user,
            merchant_uid="1475633246629",
            customer_name="asd",
            address="주소",
            address_detail="asdfdsa",
            postal_code="12345",
            phone_number="01095104344",
            possible_date_start="2011-11-24",
            possible_date_end="2011-11-24",
            possible_time_start="11:22 AM",
            possible_time_end="11:22 AM",
            total_price=self.cart.total_price,
        )
        self.assertEquals(1, create.call_count)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    相关资源
    最近更新 更多