在单元测试异步操作时设置自己的NDB Future对象值

Jon*_*era 0 google-app-engine python-2.7 app-engine-ndb google-cloud-datastore

我正在为Google App Engine应用程序(Python)编写一些单元测试.我正在使用模拟库来模拟NDB tasklet.

但是,因为tasklet返回Future对象,我想知道如何实例化并使用我自己的自定义NDB Future对象,我可以将其作为mock的行为的一部分返回.如果没有这种能力,我完全不知道如何模拟ndb tasklet以验证在tasklet中调用了正确的方法.

在这个例子中.async_datastore_update()用@ ndb.toplevel修饰.在这个函数里面,有一个我要模拟的NDB tasklet:yield self._async_get_specialist(specialist_name)

a_mgr = data_manager.AchievementsHandler()

# Initiate data store sync and flush async to force result
future = a_mgr.async_datastore_update()
future.get_result()  # Flushes out the self.async_get_specialist() tasklet's results

# Continue testing...
Run Code Online (Sandbox Code Playgroud)

没有嘲弄self.async_get_specialist(),这可以通过刷新顶级函数中的异步进程来实现.

但是,当我模拟出来self.async_get_specialist()验证行为时,我在调用future的get_result()方法时遇到异常:

# Here, we mock out a future object, as per GAE docs
promise_obj_stub = ndb.Future()

a_mgr = data_manager.AchievementsHandler()
a_mgr._async_get_specialist = mock.Mock(return_value=promise_obj_stub) 

# Initiate data store sync and flush async to force result
future = a_mgr.async_datastore_update()
future.get_result()  # Throws a RuntimeError exception b/c result is never assigned to the Future object
Run Code Online (Sandbox Code Playgroud)

App Engine的文档似乎并不说明有一种方法与今后的工作对象不是检查来自GAE的API的结果等.即我没有在文档中看到Future.set_return_value()的影响.

有人知道a)单元测试tasklets的最佳方法吗?或者b)假设我的方法有意义,如何将值传递给ndb Future对象?

Jon*_*era 5

哈!在使用ndb Future类之后,看起来Future实例有一个set_result()方法可以让您将自己的信息传递给未来(目前未在GAE Future类文档中列出.因此,以下代码运行得非常好:

# Here, we mock out a future object, as per GAE docs
promise_obj_stub = ndb.Future()

a_mgr = data_manager.AchievementsHandler()
a_mgr._async_get_specialist = mock.Mock(return_value=promise_obj_stub) 

# Initiate data store sync and flush async to force result
future = a_mgr.async_datastore_update()

promise_obj_stub.set_result(['list', 'of', 'results', 'i', 'needed'])  # set a result on the Future obj

future.get_result()  # Works like a charm now

# Continue testing as usual
Run Code Online (Sandbox Code Playgroud)