简体   繁体   中英

Python, using more than 20 times mock.patch.object() and too many statically nested blocks error

I need to write the unit test code for a very fat method. And the method is calling the other methods many times, so I need to use mock for all the calling methods. but when I using mock.patch.object more than 20 times, I got the error, too many statically nested blocks.

My code looks like this,

test_fat_method(self):
instance = FatClass()
with mock.patch.object(instance, '_method_1', return_value=1), \
...
with mock.patch.object(instance, '_method_22', return_value=1):
    result = instance.test_method()
    assert result

Is there any way I can avoid the error?

There are 2 alternatives to use mock.patch other than with context switch.

As decorators

As we're binding decorators in the method, we are appending items on *args from methods.

The bad part of this implementation, is handle with a list of mocks with no name.

from unittest.mock import patch


class Class:
    def func_1():
        return True
    def func_2():
        return True
    def func_3():
        return True

@patch.object(Class, 'func_1')
@patch.object(Class, 'func_2')
@patch.object(Class, 'func_3')
def test_class(*args):
    args[0].return_value = 3 # This is the last object patched.
    args[1].return_value = 2 # This is the second object patched.
    args[2].return_value = 1 # This is the first object patched.
    assert len(args) == 3    # Quantity of items in args (3 decorators.)
    assert Class().func_1() == 1
    assert Class().func_2() == 2
    assert Class().func_3() == 3

If you have any doubts about the order of decorators take a look at this answer

As obejcts

This solution is more verbose, but easier to maintain. However, I would choice this approach.

def test_class_alternative():
    mock_func_1 = patch('Class.func_1', return_value=1)
    mock_func_2 = patch('Class.func_2', return_value=2)
    mock_func_3 = patch('Class.func_3', return_value=3)

    assert Class().func_1() == 1
    assert Class().func_2() == 2
    assert Class().func_3() == 3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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