def get_boolean_response():
response = io.prompt('y/n').lower()
while response not in ('y', 'n', 'yes', 'no'):
io.echo('Not a valid input. Try again'])
response = io.prompt('y/n').lower()
return response in ('y', 'yes')
My Test code:
@mock.patch('io')
def test_get_boolean_response(self, mock_io):
#setup
mock_io.prompt.return_value = ['x','y']
result = operations.get_boolean_response()
#test
self.assertTrue(result)
self.assertEqual(mock_io.prompt.call_count, 2)
替换代码2】只是一个独立于平台(Python 2和3)的 "输入 "版本。所以最终我试图模拟出用户的输入。我试着用一个列表作为返回值,但这似乎并不奏效。
你可以看到,如果返回值是无效的,我就会在这里得到一个无限的循环。所以我需要一种方法来最终改变返回值,这样我的测试才会真正完成。
(回答这个问题的另一种可能方式是解释我如何在单元测试中模仿用户输入)
不是杜撰的this question主要是因为我没有能力改变输入。
答复的意见之一是this question是沿着同样的思路,但没有提供答案/评论。
3 个回答
0 人赞同
你可以指定一个可迭代的到side_effect
,并且每次调用mock都会返回序列中的下一个值。
>>> from unittest.mock import Mock
>>> m = Mock()
>>> m.side_effect = ['foo', 'bar', 'baz']
'foo'
'bar'
'baz'
Quoting the Mock()
documentation:
If side_effect is an 可迭代的 then each call to the mock will return the next value from the 可迭代的.
0 人赞同
对于多个返回值,我们可以使用side_effect在补丁初始化过程中也是如此,并把可迭代的东西传给它
sample.py
def hello_world():
test_sample.py
from unittest.mock import patch
from sample import hello_world
@patch('sample.hello_world', side_effect=[{'a': 1, 'b': 2}, {'a': 4, 'b': 5}])
def test_first_test(self, hello_world_patched):
assert hello_world() == {'a': 1, 'b': 2}
assert hello_world() == {'a': 4, 'b': 5}
assert hello_world_patched.call_count == 2
0 人赞同
你也可以对多个返回值使用补丁。
@patch('Function_to_be_patched', return_value=['a', 'b', 'c'])
请记住,如果你为一个方法使用了多个补丁,那么它的顺序将是这样的。
@patch('a')