如何测试信号中的异常?

时间:2018-04-14 21:55:13

标签: python django unit-testing

我有一个信号:

create_flat_referral = django.dispatch.Signal(providing_args=["request", "user"])

我有一个接收器:

@receiver(create_flat_referral, sender=None)
def save_flat_referral(sender, request, user, **kwargs):

    referral_link = request.POST.get('referral', None)
    if not referral_link:
        referral_link = request.GET.get('ref', None)

    try:
        if referral_link:
            link = Link.objects.get(token = referral_link)
            referral = FlatReferral.objects.create(
                referrer = link.user,
                referred = user
            )
    except Link.DoesNotExist:
        logger.exception('...')
    except ValidationError:
        logger.exception('...')

我想用测试来涵盖所有例外情况。

enter image description here

除了我想要的内容assertRaises之外,我还希望得到assertRaisesMessage

最好的方法是什么?

如果我试图做这样的事情:

    self.assertRaises(
        ValidationError,
        lambda: signals.create_flat_referral.send(
            sender = None,
            request = post_request,
            user = self.referred
        )
    )

我没通过测试:

  

AssertionError:lambda

未引发ValidationError

2 个答案:

答案 0 :(得分:-1)

  

AssertionError:lambda

未引发ValidationError

callable是func名称的定义,而不是func()调用

`assertRaises(exception, callable, *args, **kwds)`

例如,这将起作用cal_exp是func name

 self.assertRaises(OverflowError, MathOverFlow().cal_exp, 2)

这不起作用,因为cal_exp(2)对于assert

无效
 self.assertRaises(OverflowError, MathOverFlow().cal_exp(2))

我个人更喜欢这种方式:

d = {'sender': None, 'request': post_request, 'user': self.referred}

with self.assertRaises(ValidationError):
    signals.create_flat_referral.send(**d)

或者**kwargs的功能名称,而不是func(**kwargs)

self.assertRaises(ValidationError, signals.create_flat_referral.send, **d)

我找不到lamda的地方,或者至少它让事情变得比这里更复杂。

答案 1 :(得分:-1)

您需要测试您的信号处理程序本身 - 而不是Django的信号框架(由Django本身进行彻底测试)。因此,您不需要经历触发实际信号的所有麻烦 - 您可以直接使用模拟参数调用您的函数,并检查它是否正确处理它们 - 如下所示:

from django.test import TestCase, RequestFactory

class MySignalTestCase(TestCase):

    def test_link_does_not_exist(self):
        # Create a dummy request that you can give to your signal handler
        factory = RequestFactory()
        request = factory.post('/')   # Pass appropriate params here if needed

       with self.assertRaises(ValidationError):
           # sender isn't used, hence you can just pass None there.
           save_flat_referral(sender=None, request=request)