在另一个方法中模拟方法中的输入

时间:2021-05-30 15:31:00

标签: python unit-testing methods constructor mocking

我想学习如何模拟必须输入的输入,当在另一个方法中调用方法时
在这个特定的例子中,我想模拟用户输入,当 pass_arg() 方法执行时需要输入

构造函数

def __init__(self):
    super().__init__(argument_default=argparse.SUPPRESS)
    self.add_argument("-u", help="Login. Required argument", default="None")
    self.add_argument("-p", help="Password", default="None")
    self.add_argument("-dir", help="path to directory. Required Argument", default="None")
    self.__args: dict = vars(self.parse_args())
    self.pass_arg()

pass_arg()

def pass_arg(self):
    arg_p: str = self.__args.get('p')
    if arg_p == "None":
        arg_p = getpass()
    else:
        print("Your password was typed in as argument in CLI. Everyone could see that!")

我试过了:

@patch('builtins.input', side_effect=['pass'])
def test_no_arguments(self) -> None:
    """Simulates situation when no arguments have been typed in"""
    self.parser = ConfigedParser()
    self.assertEqual(self.parser.get_args(), {'u': 'None', 'p': 'None', 'dir': 'None'})

** 在下面的代码示例中,解决了我的问题。我只是嘲笑了整个方法 getpass() **

    def test_no_arguments(self) -> None:
    """Simulates situation when no arguments have been typed in CLI"""
    with patch.object(ConfigedParser, 'pass_arg', new=self.moc_get_pass):
        self.parser = ConfigedParser()
        self.assertEqual(self.parser.get_args(), {'u': 'None', 'p': 'None', 'dir': 'None'})

def moc_get_pass(self):
    return

1 个答案:

答案 0 :(得分:0)

patch 的作用是用可以自由配置的 Mock 对象临时替换 input 引用背后的值。
请阅读 side_effect 参数的工作原理:official documentation

总而言之,您可以:

  • 当修补的引用被调用时,给它一个异常引发,
  • 当修补的引用被多次调用时,给它一个要返回的值列表,一个一个地返回
  • 给它一个函数来调用而不是被修补的引用,模拟将返回函数提供的值

在这里,您将 Mock 配置为在第一次调用 "pass" 时返回字符串 input。它不会用 pass 语句替换实际调用。因此,实际上调用了 input(),但调用的不是 builtins.input 方法,而是您的模拟,它返回 "pass"

您没有发布包含 input 调用的代码,因此我无法提供进一步的帮助,但我建议您使用 return_value="whatever" 而不是 side_effect 以避免这种情况错误。

另外,在发布问题时花点时间创建一个 Minimal Reproducible Example,这很有帮助。