Python在if语句中测试raw_input,raw_input

时间:2014-01-13 09:21:16

标签: python unit-testing mocking

我正在测试我的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'

但是如何检查无声明?如何在模拟中进行模拟?

3 个答案:

答案 0 :(得分: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 documentation

  

如果side_effect是可迭代的,那么对mock的每次调用都将从iterable返回下一个值。   side_effect也可以是任何可迭代对象。对mock的重复调用将返回iterable中的值(直到iterable耗尽并引发StopIteration):

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

答案 1 :(得分:2)

使用副作用应该可以解决问题,我发现以下内容非常明确并避免多个带块:

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'

答案 2 :(得分: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'