Mock - 根据 Mock 对象更改返回值

问题描述 投票:0回答:1

我正在尝试模拟

unittest
中的某些对象,但我需要根据在
Mock
语句中评估的
if
对象返回不同的布尔值。

我正在测试的功能看起来像这样:

def run_tests():
    failed_tests = []
    for test in get_tests():
       if validate_schema(test):
           #some logic
       else:
           failed_tests.append(test)
    return failed_tests

def validate_schema(test):
    if test == foo:
        return True
    else:
        return False

例如,我想做

for
循环的三次迭代,其中前两次迭代
validate_schema()
返回
False
,第三次返回
True

我的单元测试看起来像这样,试图实现这一目标:

import unittest

from unittest.mock import Mock, patch
from app.test_runner import run_tests

MOCK_TEST_CASE_ONE = Mock()
MOCK_TEST_CASE_TWO = Mock()
MOCK_TEST_CASE_THREE = Mock()

class TestRunTests(unittest.TestCase):
    @patch('app.test_extractor.get_tests')
    @patch('app.test_parser.validate_schema')
    def test_two_fail_one_pass_test_on_validation(self, mock_get_tests, mock_validate_schema):
        mock_get_unit_tests.return_value = [MOCK_TEST_CASE_ONE, MOCK_TEST_CASE_TWO, MOCK_TEST_CASE_THREE]
        validation_results = [False, False, True]
        mock_validate_schema.side_effect = validation_results
        self.assertEqual(run_tests(), [MOCK_TEST_CASE_ONE, MOCK_TEST_CASE_TWO])


if __name__ == "__main__":
    unittest.main()

但是,运行测试时,测试在

mock_validate_schema.side_effect = validation_results
上失败,因为它返回错误
TypeError: 'bool' object is not iterable

我尝试过遵循这个类似的示例如何在for循环中动态模拟python函数的结果?但区别在于

foo
接受一组项目,而我正在尝试评估
 Mock
对象,所以我不确定如何评估前两个 Mock 对象以返回
False
和第三个
True

unit-testing mocking python-unittest
1个回答
0
投票

经过大量研究和尝试,我找出了问题所在,感谢我偶然发现的这篇文章https://nedbatchelder.com/blog/202202/why_your_mock_still_doesnt_work.html

测试函数参数中的修补顺序需要按照装饰器的调用方式从后到前排列。最初我的测试函数参数看起来像这样:

@patch('app.test_extractor.get_tests')
@patch('app.test_parser.validate_schema')
def test_two_fail_one_pass_test_on_validation(self, mock_get_tests, mock_validate_schema):

但是

mock_get_tests
mock_validate_schema
需要这样切换:

@patch('app.test_extractor.get_tests')
@patch('app.test_parser.validate_schema')
def test_two_fail_one_pass_test_on_validation(self, mock_validate_schema, mock_get_tests):

单元测试的其余部分实际上很好,现在可以工作了,所以现在看起来像

import unittest

from unittest.mock import Mock, patch
from app.test_runner import run_tests

MOCK_TEST_CASE_ONE = Mock()
MOCK_TEST_CASE_TWO = Mock()
MOCK_TEST_CASE_THREE = Mock()

class TestRunTests(unittest.TestCase):
    @patch('app.test_extractor.get_tests')
    @patch('app.test_parser.validate_schema')
    def test_two_fail_one_pass_test_on_validation(self, mock_validate_schema, mock_get_tests):
        mock_get_unit_tests.return_value = [MOCK_TEST_CASE_ONE, MOCK_TEST_CASE_TWO, MOCK_TEST_CASE_THREE]
        validation_results = [False, False, True]
        mock_validate_schema.side_effect = validation_results
        self.assertEqual(run_tests(), [MOCK_TEST_CASE_ONE, MOCK_TEST_CASE_TWO])


if __name__ == "__main__":
    unittest.main()
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.