后续 this question .
我在 for 循环中接受用户输入并编写了一个测试用例 test_apple_record
。在这个 for 循环中,它查询一个可以随机返回 True 或 False 的方法 self.dispatch_requested()
(未显示)。基于这个答案,代码会要求用户输入另一个信息——托盘应该发送到哪里。
我正在为 mock.patch
使用 side_effect
参数。如何使用模拟自动传递酒店号码作为用户输入?我仍然想继续将数字 [5, 6, 7]
传递给 for 循环,但现在还想根据 self.dispatch_requested()< 的响应传递酒店编号
谢谢
class SomeClass(unittest.TestCase):
def apple_counter(self):
apple_record = {}
for i in range(3):
apple_tray = input("enter tray number:")
apple_record[apple_tray] = (i+1)*10
print("i=%d, apple_record=%s"%(i, apple_record))
if self.dispath_requested():
number = input("Enter Hotel number to dispatch this tray:")
update_hotel_record(number, apple_tray)
def update_hotel_record(self, number, tray):
self.hotel_record[number] = tray
def test_apple_record(self):
with mock.patch('builtins.input', side_effect=[5, 6, 7]):
self.apple_counter()
最佳答案
您实际上希望您的 side_effect 看起来像这样:
m_input.side_effect = [1, 100, 2, 200, 3, 300]
每次调用输入法,都会返回下一项。所以每次在你的循环中,你都会调用 input 两次。
此外,我不知道您的单元测试的最终结构,但是,看到您在循环中调用的第二个输入周围有一个条件语句,您可能应该围绕该方法设置一个模拟以始终返回没错。
当你到达你想要测试你的代码时 self.dispath_requested() 返回 false 的场景时,你必须记住第二个输入不会被调用,所以你的 side_effect 必须相应地重写以匹配您的代码的预期行为。
此外,最后,我再次不确定您的代码实际是什么样子,但是,根据您似乎在同一类下拥有实际实现和测试代码的方式,我强烈建议您不要这样做。尝试类似这样的结构:
创建一个单独的测试类:
class Tests(unittest.TestCase):
def setUp(self):
self.s = SomeClass()
@patch('__builtin__.input')
def test_apple_record(self, m_input):
m_input.side_effect = [1, 100, 2, 200, 3, 300]
self.s.apple_counter()
if __name__ == '__main__':
unittest.main()
因此,您创建了 SomeClass 的一个实例,然后这实际上会让您更容易地模拟对象的属性,这将使您的单元测试更容易编写。
您还会注意到我使用了装饰器 (@patch) 而不是“with”上下文。这是个人喜好,我发现使用装饰器更容易阅读代码。
希望这对您有所帮助。
关于Python 使用 mock 进行多个用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32682428/