使用 pytest,当所述方法提示输入另一个输入并且处于连续循环中时,如何测试输入是否会导致预期的方法调用?
Using pytest, how do you test that an input leads to an expected method call, when said method prompts for another input, and is in a continuous loop?
Substituting the built-in input function's value with a string 通常用于测试方法是否对该输入具有预期的响应。将使用像 monkeypatch 这样的工具来执行此操作,然后我们断言调用方法 returns 是预期值。
Even when you call another method inside the method,如果第二个有可预测的return值,你可以使用类似的方法。
现在,如果该方法的预期行为是调用一个也要求输入的方法怎么办?目的是确保程序到达第二个输入提示(确认第一个输入具有预期结果)。有没有办法单独断言?
示例:
class TwoInputs:
def method_a(self):
self.action = input("Enter something: ")
if self.action == "jump":
self.method_b()
self.method_a()
elif self.action == "exit":
quit()
def method_b(self):
while True:
self.action = input("Enter some other thing: ")
if self.action == "1":
print("Hello world.")
break
else:
print("Invalid input.")
在上面的上下文中,您将如何测试 method_a 成功调用 method_b,并在那里结束测试?如果我通过将其更改为“跳跃”来对输入进行猴子修补,那么只需调用 method_a,相同的输入将在 method_b 中被视为无效,然后将连续循环。
要检查 method_b
是否已被调用,您必须模拟它。正如你提到的,你还必须模拟 input
,并确保它的 returns 值会导致程序结束,而不是递归:
@mock.patch("two_inputs.TwoInputs.method_b")
@mock.patch("two_inputs.input")
@mock.patch("two_inputs.quit")
def test_that_a_calls_b(mock_quit, mock_input, mocked_method_b):
# consecutive call results - second call is from inside `method_a`
mock_input.side_effect = ["jump", "exit"]
two_inputs = TwoInputs()
two_inputs.method_a()
mocked_method_b.assert_called_once()
这假设您的 class 位于项目根目录的 two_inputs.py
。
对于你的情况,我还添加了模拟系统函数 quit
(否则测试会退出),但我猜你不会在你的真实代码中调用它。
Substituting the built-in input function's value with a string 通常用于测试方法是否对该输入具有预期的响应。将使用像 monkeypatch 这样的工具来执行此操作,然后我们断言调用方法 returns 是预期值。
Even when you call another method inside the method,如果第二个有可预测的return值,你可以使用类似的方法。
现在,如果该方法的预期行为是调用一个也要求输入的方法怎么办?目的是确保程序到达第二个输入提示(确认第一个输入具有预期结果)。有没有办法单独断言?
示例:
class TwoInputs:
def method_a(self):
self.action = input("Enter something: ")
if self.action == "jump":
self.method_b()
self.method_a()
elif self.action == "exit":
quit()
def method_b(self):
while True:
self.action = input("Enter some other thing: ")
if self.action == "1":
print("Hello world.")
break
else:
print("Invalid input.")
在上面的上下文中,您将如何测试 method_a 成功调用 method_b,并在那里结束测试?如果我通过将其更改为“跳跃”来对输入进行猴子修补,那么只需调用 method_a,相同的输入将在 method_b 中被视为无效,然后将连续循环。
要检查 method_b
是否已被调用,您必须模拟它。正如你提到的,你还必须模拟 input
,并确保它的 returns 值会导致程序结束,而不是递归:
@mock.patch("two_inputs.TwoInputs.method_b")
@mock.patch("two_inputs.input")
@mock.patch("two_inputs.quit")
def test_that_a_calls_b(mock_quit, mock_input, mocked_method_b):
# consecutive call results - second call is from inside `method_a`
mock_input.side_effect = ["jump", "exit"]
two_inputs = TwoInputs()
two_inputs.method_a()
mocked_method_b.assert_called_once()
这假设您的 class 位于项目根目录的 two_inputs.py
。
对于你的情况,我还添加了模拟系统函数 quit
(否则测试会退出),但我猜你不会在你的真实代码中调用它。