Python模拟多个返回值
我正在使用pythons mock.patch并想要更改每个调用的返回值。 这里是警告:被修补的函数没有input,所以我不能根据input更改返回值。
这里是我的代码供参考。
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')
我的testing代码:
@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
只是一个平台独立(python 2和3)版本的“input”。 所以最终我试图嘲笑用户的input。 我已经尝试使用返回值的列表,但是不缝合工作。
你可以看到,如果返回值是无效的,我会在这里得到一个无限循环。 所以我需要一种方法来最终改变返回值,以便我的testing实际完成。
(另一个可能的方法来回答这个问题可能是解释我怎么可以在unit testing中模仿用户input)
不是这个问题的重复,主要是因为我没有能力改变input。
对这个问题的答复之一是同样的意见,但没有提供答复/评论。
您可以将一个迭代器分配给side_effect
,并且每次调用时side_effect
都会返回序列中的下一个值:
>>> from unittest.mock import Mock >>> m = Mock() >>> m.side_effect = ['foo', 'bar', 'baz'] >>> m() 'foo' >>> m() 'bar' >>> m() 'baz'
引用Mock()
文档 :
如果side_effect是可迭代的,那么对模拟的每次调用将返回来自迭代器的下一个值。
另外,testingresponse is not 'y' or 'n' or 'yes' or 'no'
不起作用。 你在问是否expression式(response is not 'y')
是真的,或者'y'
是true(总是这样,一个非空string总是true)等等。 独立 。 请参阅如何针对多个值testing一个variables?
你也不应该用来testing一个string。 CPython解释器可能会 在某些情况下重用string对象,但这不是您应该依赖的行为。
因此,使用:
response not in ('y', 'n', 'yes', 'no')
代替; 这将使用平等testing( ==
)来确定response
引用具有相同内容(值)的string。
response == 'y' or 'yes'
。 请response in ('y', 'yes')
使用response in ('y', 'yes')
。