How to mock a tornado coroutine function using mock framework for unit testing?

后端 未结 1 1897
感动是毒
感动是毒 2021-02-02 12:57

The title simply described my problem. I would like to mock \"_func_inner_1\" with specific return value. Thanks for any advises :)

code under test:

from         


        
相关标签:
1条回答
  • 2021-02-02 13:35

    There are two issues here:

    First is the interaction between @mock.patch and @gen_test. gen_test works by converting a generator into a "normal" function; mock.patch only works on normal functions (as far as the decorator can tell, the generator returns as soon as it reaches the first yield, so mock.patch undoes all its work). To avoid this problem, you can either reorder the decorators (always put @mock.patch before @gen_test, or use the with form of mock.patch instead of the decorator form.

    Second, coroutines should never raise an exception. Instead, they return a Future which will contain a result or an exception. The special Return exception is encapsulated by the coroutine system; you would never raise it from a Future. When you create your mocks, you must create the appropriate Future and set it as the return value instead of using side_effect to raise on exception.

    The complete solution is:

    from tornado.concurrent import Future
    from tornado.gen import coroutine, Return
    from tornado.testing import gen_test
    from tornado.testing import AsyncTestCase
    
    import mock
    
    @coroutine
    def _func_inner_1():
        raise Return(1)
    
    @coroutine
    def _func_under_test_1():
        temp = yield _func_inner_1()
        raise Return(temp + 1)
    
    class Test123(AsyncTestCase):
    
        @mock.patch(__name__ + '._func_inner_1')
        @gen_test
        def test_1(self, mock_func_inner_1):
            future_1 = Future()
            future_1.set_result(9)
            mock_func_inner_1.return_value = future_1
            result_1 = yield _func_inner_1()
            print 'result_1', result_1
            result = yield _func_under_test_1()
            self.assertEqual(10, result, result)
    
    import unittest
    unittest.main()
    
    0 讨论(0)
提交回复
热议问题