我如何模拟一个django信号处理程序? [英] How do I mock a django signal handler?
问题描述
我有一个signal_handler通过装饰器连接,像这样非常简单的一个:
@receiver(post_save,sender =
/ pre>
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调用它的次数。我现在的代码是这样的:
def test_cache():
with mock.patch('myapp。 myfile.signal_handler_post_save_user')作为mocked_handler:
#做的东西,将调用post_save的用户
self.assert_equal(mocked_handler.call_count,1)
这里的问题是即使嘲笑原始的信号处理程序,很可能是因为
@receiver
正在将信号处理程序的副本存储在某个地方,所以我正在嘲弄错误的代码。
所以问题:我如何模拟我的信号处理程序使我的测试工作?
请注意,如果我将信号处理程序更改为:
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
而是,一切都按预期工作。解决方案所以,我最终得到了一种解决方案:嘲笑信号处理程序只是意味着将模拟本身连接到信号,所以这正是我所做的:
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')
#将调用user
self.assertEquals(mocked_handler.call_count,1)的标题django
#self.assert_equal(mocked_handler.call_count,1)#当使用django-nose
<注意
请注意,
mock中的
才能使autospec = True
需要补丁post_save.connect
正确处理MagicMock
,否则django会引发一些异常,连接将失败。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
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)
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)
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
Notice that
autospec=True
inmock.patch
is required in order to makepost_save.connect
to correctly work on aMagicMock
, otherwise django will raise some exceptions and the connection will fail.这篇关于我如何模拟一个django信号处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!