[英]How to test if a model was saved before passed on to task queue?
In the following method the correct behaviour would to to save the news
model before passing its id to the asynchronous Task queue for further processing. 在以下方法中,正确的行为是在将news
模型的ID传递到异步Task队列进行进一步处理之前 ,保存news
模型。 Otherwise the task queue has the older version. 否则,任务队列具有较旧的版本。
As you can see I have made a mistake and am saving the model after sending its id to the task queue. 如您所见,我将一个ID发送到任务队列后犯了一个错误,正在保存模型。
def save_scraped_body_into_model(url_string):
news = ndb.Key(urlsafe=url_string).get()
...
news.body = result
news.stage = 1
taskqueue.Task(url='/api/v1.0/worker/bbc-stage-2', headers=header,
payload=json.dumps({'news_url_string': news.key.urlsafe()})).add(queue_name='newstasks')
news.put()
How do I possibly test for that? 我该如何测试? My test below passes as long as the model was saved. 只要保存了模型,我下面的测试就会通过。 But thats wrong, the order matters, and this test doesn't capture it !!! 但是那是错误的,顺序很重要,并且该测试无法捕获它! Is there a way to achieve this with mock? 有没有办法通过模拟来实现这一目标?
def test_news_instance_saved_before_next_stage(self, get_head):
BBCSpider.save_scraped_body_into_model(self.news.key.urlsafe())
context = ndb.get_context()
context.clear_cache()
news = ndb.Key(urlsafe=self.news.key.urlsafe()).get()
self.assertEqual(news.stage, 1)
I'm doing these kind of tests by using patch
from unittest.mock
framework . 我正在通过使用unittest.mock
框架中的 patch
进行此类测试。
When I need to do test like this the first thing I do is looking for a point where I can put a hook. 当我需要像这样进行测试时,我要做的第一件事就是寻找可以插入挂钩的点。 Then I patch the hook and use side_effect
callback to do the test. 然后我修补钩子,并使用side_effect
回调进行测试。
In your case the hook will be BBCSpider.taskqueue.Task
and its side_effect
something like this: 在您的情况下,该钩子将是BBCSpider.taskqueue.Task
及其它的side_effect
,如下所示:
lambda *args,**kwargs: self.assertEqual(1, ndb.Key(urlsafe=self.news.key.urlsafe()).get().stage)
So your test become: 因此您的测试变为:
@patch('BBCSpider.taskqueue.Task', autospec=True)
def test_news_instance_saved_before_next_stage(self, get_head, mock_task):
def check_if_model_saved(*args,**kwargs):
news = ndb.Key(urlsafe=self.news.key.urlsafe()).get()
self.assertEqual(news.stage,1)
mock_task.side_effect = check_if_model_saved
BBCSpider.save_scraped_body_into_model(self.news.key.urlsafe())
self.assertTrue(mock_task.called)
Note autospec=True
is not mandatory but I like to use it every time I do a patch to avoid silly errors. 注意autospec=True
不是强制性的,但我喜欢在每次打补丁时都使用它,以免出现愚蠢的错误。
I'm apologize if the code contains some mistake (I cannot test it without considerable effort) but I hope the idea is clear. 如果代码中包含一些错误,我深表歉意(我必须花费大量精力才能对其进行测试),但我希望这个主意很明确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.