首页 > 解决方案 > Python:如何模拟接受列表参数的调用并断言列表参数的第一项

问题描述

我正在使用 python mock 并且有一个单元测试,我需要确保调用了一个函数,并且它的第一个元素是一个特定的值。考虑这个简短的例子:

import unittest
from mock import patch, ANY

class foo():
    def something(self, a, b):
        print a,b

class footest(unittest.TestCase):
    def testany(self):
        f = foo()
        with patch.object(f, "something", autospec=True) as mock_something:
            f.something(1, [2,3,4])
            mock_something.assert_called_with(ANY, [2, ANY])

unittest.main()

当然这失败了,因为我传递了一个三元素列表而不是二元素列表。我可以通过自己检查 mock_something.calls 并拆分参数来解决这个问题,但我想知道是否存在任何内置的模拟功能,可以轻松地断言列表可以包含任意数量的 ANY?

标签: pythonmocking

解决方案


你可能感兴趣mock.call_args

链接:https ://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.call_args

#!/usr/bin/env python

import unittest
from mock import patch, ANY

class foo():
    def something(self, a, b):
        print(a, b)

class footest(unittest.TestCase):
    def testany(self):
        f = foo()
        with patch.object(f, "something", autospec=True) as mock_something:
            f.something(1, [2,3,4])
            # mock_something.assert_called_with(ANY, [2, ANY])
            assert mock_something.call_count == 1

            received_args = mock_something.call_args.args
            target_arg = received_args[1]
            assert target_arg[0] == 2

            print("Result of mock_something.call_args", mock_something.call_args)
            print("Result of mock_something.call_args.args", mock_something.call_args.args)

unittest.main()

输出:

(venv) nponcian 2020_7Jul_14_StackOVerflowPytest$ ./script.py 
Result of mock_something.call_args call(1, [2, 3, 4])
Result of mock_something.call_args.args (1, [2, 3, 4])
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

推荐阅读