简体   繁体   English

如何在传递到任务队列之前测试是否保存了模型?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM