如何模拟 django 信号处理程序?

How do I mock a django signal handler?(如何模拟 django 信号处理程序?)
本文介绍了如何模拟 django 信号处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个通过装饰器连接的 signal_handler,就像这个非常简单的:

I have a signal_handler connected through a decorator, something like this very simple one:

@receiver(post_save, sender=User, 
          dispatch_uid='myfile.signal_handler_post_save_user')
def signal_handler_post_save_user(sender, *args, **kwargs):
   # do stuff

我想做的是用模拟库 http://www.voidspace 模拟它.org.uk/python/mock/ 在测试中,检查 django 调用它的次数.我现在的代码是这样的:

What I want to do is to mock it with the mock library http://www.voidspace.org.uk/python/mock/ in a test, to check how many times django calls it. My code at the moment is something like:

def test_cache():
    with mock.patch('myapp.myfile.signal_handler_post_save_user') as mocked_handler:
        # do stuff that will call the post_save of User
    self.assert_equal(mocked_handler.call_count, 1)

这里的问题是即使模拟了原始信号处理程序也会被调用,很可能是因为 @receiver 装饰器在某处存储了信号处理程序的副本,所以我模拟了错误的代码.

The problem here is that the original signal handler is called even if mocked, most likely because the @receiver decorator is storing a copy of the signal handler somewhere, so I'm mocking the wrong code.

所以问题是:我如何模拟我的信号处理程序以使我的测试工作?

So the question: how do I mock my signal handler to make my test work?

请注意,如果我将信号处理程序更改为:

Note that if I change my signal handler to:

def _support_function(*args, **kwargs):
    # do stuff

@receiver(post_save, sender=User, 
          dispatch_uid='myfile.signal_handler_post_save_user')
def signal_handler_post_save_user(sender, *args, **kwargs):
   _support_function(*args, **kwargs)

我改为模拟 _support_function,一切都按预期工作.

and I mock _support_function instead, everything works as expected.

推荐答案

所以,我最终得到了一种解决方案:模拟信号处理程序只是意味着将模拟本身连接到信号,所以这正是我做了:

So, I ended up with a kind-of solution: mocking a signal handler simply means to connect the mock itself to the signal, so this exactly is what I did:

def test_cache():
    with mock.patch('myapp.myfile.signal_handler_post_save_user', autospec=True) as mocked_handler:
        post_save.connect(mocked_handler, sender=User, dispatch_uid='test_cache_mocked_handler')
        # do stuff that will call the post_save of User
    self.assertEquals(mocked_handler.call_count, 1)  # standard django
    # self.assert_equal(mocked_handler.call_count, 1)  # when using django-nose

请注意,mock.patch 中的 autospec=True 是必需的,以使 post_save.connect 能够在 上正确工作MagicMock,否则django会抛出一些异常,连接会失败.

Notice that autospec=True in mock.patch is required in order to make post_save.connect to correctly work on a MagicMock, otherwise django will raise some exceptions and the connection will fail.

这篇关于如何模拟 django 信号处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

patching a class yields quot;AttributeError: Mock object has no attributequot; when accessing instance attributes(修补类会产生“AttributeError:Mock object has no attribute;访问实例属性时)
How to mock lt;ModelClassgt;.query.filter_by() in Flask-SqlAlchemy(如何在 Flask-SqlAlchemy 中模拟 lt;ModelClassgt;.query.filter_by())
FTPLIB error socket.gaierror: [Errno 8] nodename nor servname provided, or not known(FTPLIB 错误 socket.gaierror: [Errno 8] nodename nor servname provided, or not known)
Weird numpy.sum behavior when adding zeros(添加零时奇怪的 numpy.sum 行为)
Why does the #39;int#39; object is not callable error occur when using the sum() function?(为什么在使用 sum() 函数时会出现 int object is not callable 错误?)
How to sum in pandas by unique index in several columns?(如何通过几列中的唯一索引对 pandas 求和?)