Python测试原始输入,if语句中的原始输入

4

我正在测试我的Python代码,并且对raw_input有疑问。这是我的函数:

def answer():
    ans = raw_input('enter yes or no')
    if ans == 'yes':
        print 'you entered yes'
        return 'yes'
    if ans == 'no':
        some_value = raw_input('enter some value: ')
        print 'you entered no'
        return some_value

我这样测试第一个if语句:

with mock.patch('__builtin__.raw_input', return_value= 'yes'):
    assert answer() == 'yes'

但是,我如何检查no语句?我如何在mock中嵌套mock?

3个回答

4

使用 side_effect

with mock.patch('__builtin__.raw_input', side_effect=['yes']):
    assert answer() == 'yes'
with mock.patch('__builtin__.raw_input', side_effect=['no', 'maybe']):
    assert answer() == 'maybe'

根据Mock文档所述:

mock是一个与Python中单元测试相关的库。

If side_effect is an iterable then each call to the mock will return the next value from the iterable. The side_effect can also be any iterable object. Repeated calls to the mock will return values from the iterable (until the iterable is exhausted and a StopIteration is raised):

>>>
>>> m = MagicMock(side_effect=[1, 2, 3])
>>> m()
1
>>> m()
2
>>> m()
3
>>> m()
Traceback (most recent call last):
  ...
StopIteration

2
使用副作用应该可以解决问题,我发现以下代码非常清晰,避免了多个with块的使用:
def my_side_effect(*args):  # each argument will be the return_value of one call
    for el in args:
        yield el  # we use a generator to return different value each time

with mock.patch('__builtin__.raw_input') as mocked:  # here the mocked object is accessible in the block
    mocked.side_effect = my_side_effect('yes')  # here one call that return 'yes'
    assert answer() == 'yes'
    mocked.side_effect = my_side_effect('no', 'maybe')  # two calls, the first return 'no', the second 'maybe'
    assert answer() == 'maybe'

我没有意识到 side_effect 可以像这样接受一个生成器。生成器总是捆绑简单状态的最简单方法。+1,只因为我不能 +10。 - abarnert

0
如果你只是模拟raw_input返回'no',它将两次返回'no',这意味着你可以断言该函数返回'no'
with mock.patch('__builtin__.raw_input', return_value='yes'):
    assert answer() == 'yes'
with mock.patch('__builtin__.raw_input', return_value='no'):
    assert answer() == 'no'

如果你想测试一下,比如说第一个输入是'no',第二个输入是'maybe'时会发生什么,你需要使用一个函数来模拟它。这个函数在第一次调用时返回不同的值,在第二次调用时返回另一个值,然后你就可以断言它返回了'maybe'。类似这样(没有测试,因为我这里没有安装mock,但应该能给你一个想法):
def fake_raw_input(once=[False]):
    if not once[0]:
        once[0] = True
        return 'no'
    return 'maybe'

with mock.patch('__builtin__.raw_input', return_value='yes'):
    assert answer() == 'yes'
with mock.patch('__builtin__.raw_input', new_callable=fake_raw_input):
    assert answer() == 'maybe'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接