python可以有多个返回值吗,Python模拟多个返回值

I am using pythons mock.patch and would like to change the return value for each call.

Here is the caveat:

the function being patched has no inputs, so I can not change the return value based on the input.

Here is my code for reference.

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)

io.prompt is just a platform independent (python 2 and 3) version of "input". So ultimately I am trying to mock out the users input. I have tried using a list for the return value, but that doesn't seam to work.

You can see that if the return value is something invalid, I will just get an infinite loop here. So I need a way to eventually change the return value, so that my test actually finishes.

(another possible way to answer this question could be to explain how I could mimic user input in a unit-test)

Not a dup of this question mainly because I do not have the ability to vary the inputs.

One of the comments of the Answer on this question is along the same lines, but no answer/comment has been provided.

解决方案

You can assign an iterable to side_effect, and the mock will return the next value in the sequence each time it is called:

>>> from unittest.mock import Mock

>>> m = Mock()

>>> m.side_effect = ['foo', 'bar', 'baz']

>>> m()

'foo'

>>> m()

'bar'

>>> m()

'baz'

If side_effect is an iterable then each call to the mock will return the next value from the iterable.

As an aside, the test response is not 'y' or 'n' or 'yes' or 'no' will not work; you are asking if the expression (response is not 'y') is true, or 'y' is true (always the case, a non-empty string is always true), etc. The various expressions on either side of or operators are independent. See How do I test one variable against multiple values?

You should also not use is to test against a string. The CPython interpreter may reuse string objects under certain circumstances, but this is not behaviour you should count on.

As such, use:

response not in ('y', 'n', 'yes', 'no')

instead; this will use equality tests (==) to determine if response references a string with the same contents (value).

The same applies to response == 'y' or 'yes'; use response in ('y', 'yes') instead.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值