我有一个通过装饰器连接的signal_handler,类似于这个非常简单的:
@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调用它多少次。我目前的代码如下:
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装饰器将信号处理程序的副本存储在某个地方,所以我在模仿错误的代码。
因此,问题是:我如何嘲笑我的信号处理程序来使我的测试工作?
请注意,如果我将信号处理程序更改为:
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,一切都像预期的那样工作。
发布于 2012-10-29 09:47:37
因此,我最终得到了一种解决方案:模拟信号处理程序仅仅意味着将模拟本身连接到信号,所以这正是我所做的:
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注意,要使autospec=True在mock.patch上正确工作,mock.patch中的post_save.connect是必需的,否则django将引发一些异常,连接将失败。
发布于 2015-10-02 18:07:43
更好的方法可能是模拟信号处理程序内部的功能,而不是模拟处理程序本身。使用OP的代码:
@receiver(post_save, sender=User, dispatch_uid='myfile.signal_handler_post_save_user')
def signal_handler_post_save_user(sender, *args, **kwargs):
do_stuff() # <-- mock this
def do_stuff():
... do stuff in here然后模拟do_stuff
with mock.patch('myapp.myfile.do_stuff') as mocked_handler:
self.assert_equal(mocked_handler.call_count, 1)发布于 2015-09-28 20:38:32
您可以通过像这样在ModelSignal上模拟django.db.models.signals.py类来模拟django信号:
@patch("django.db.models.signals.ModelSignal.send")
def test_overwhelming(self, mocker_signal):
obj = Object()这应该能起作用。请注意,这将模拟所有信号,无论您使用的是哪个对象。
如果您可能会使用mocker库,则可以这样做:
from mocker import Mocker, ARGS, KWARGS
def test_overwhelming(self):
mocker = Mocker()
# mock the post save signal
msave = mocker.replace("django.db.models.signals")
msave.post_save.send(KWARGS)
mocker.count(0, None)
with mocker:
obj = Object()这是更多的线条,但效果也很好:)
https://stackoverflow.com/questions/13112302
复制相似问题