1

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"
        )

I followed https://stackoverflow.com/a/13119150/3595632, but it doesn't work, which means, it called signal handler in real! (I checked it out using print())

Anything wrong?

Community
  • 1
  • 1
user3595632
  • 5,380
  • 10
  • 55
  • 111
  • Why not just call the function with your test? To test that the signal fires when something is created is a bit much considering it is core django. You can call the `signal.send` method with the appropriate signature as well. – theWanderer4865 Nov 07 '16 at 15:24
  • @theWanderer4865 I didn't catch what you said. Could you give me a example, please? – user3595632 Nov 07 '16 at 22:40
  • did you assert that the mock_handler was called? When your signal code is imported (when Django starts up) it will register any number of handlers to the signal - you should explicitly disconnect the other handler if you don't want it to run. There's more to be said but that would be step 1. – theWanderer4865 Nov 08 '16 at 15:10

1 Answers1

2

FWIW I followed the same, but needed to mock celery's send_task. After reading through, I did recognize, that signals are valuable and shouldn't be mocked (it's a desired action to fire them, right?), so the solution was to mock what was going on inside the signal (communication with external services). All in all I would suggest:

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)
brian
  • 509
  • 3
  • 14