sta*_*kjs 3 python unit-testing mocking
这个问题的后续。
我正在 for 循环中接受用户输入,并编写了一个测试用例test_apple_record。在此 for 循环中,它查询一个self.dispatch_requested()可以随机返回 True 或 False 的方法(未显示)。基于这个答案,代码要求用户进行另一个输入——托盘应该发送到哪里。
我正在使用side_effect的参数mock.patch。如何使用模拟自动传递酒店号码作为用户输入?我仍然想继续将数字传递[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()
Run Code Online (Sandbox Code Playgroud)
你实际上希望你的 side_effect 看起来像这样:
m_input.side_effect = [1, 100, 2, 200, 3, 300]
Run Code Online (Sandbox Code Playgroud)
每次调用输入法时,都会返回下一项。因此,每次在循环中,您都会调用 input 两次。
另外,我不知道单元测试的最终结构,但是,看到您在循环中调用的第二个输入周围有一个条件语句,您可能应该围绕该方法设置一个模拟以始终返回 True。
当您遇到要测试代码何时 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()
Run Code Online (Sandbox Code Playgroud)
因此,您创建 SomeClass 的实例,然后这实际上会让您更轻松地模拟对象的属性,这将使您的单元测试更容易编写。
您还会注意到我使用了装饰器(@patch)而不是“with”上下文。这是个人喜好,我发现使用装饰器更容易阅读代码。
希望这可以帮助。