如何用pytest monkeypatch正确模拟两次控制台输入测试overwrite_file?
解决
overwrite_file函数的测试输入模拟问题 你遇到的核心问题是:两次独立的monkeypatch.setattr会覆盖对input函数的模拟,导致所有input调用都返回最后一次设置的值,无法按顺序提供不同的输入。要解决这个问题,我们需要让input函数根据调用顺序返回不同的预设值,最简洁的方式是用迭代器来按顺序提供输入序列。
解决方案代码
修改你的测试函数,替换原来的monkeypatch部分:
def test_new_filename_if_file_exists(pickle_test_env, monkeypatch): """ is overwrite_file returning a valid new filename if filename exists and should not be overwritten? """ filename = 'already_there.pkl' new_filename = 'new.pkl' assert exists(join(pickle_test_env, filename)) # 创建输入序列迭代器,按调用顺序返回需要的输入值 input_sequence = iter(["n", new_filename]) # 每次调用input时,从迭代器中取下一个值 monkeypatch.setattr('builtins.input', lambda prompt: next(input_sequence)) assert overwrite_file(join(pickle_test_env, filename)) == join(pickle_test_env, new_filename)
工作原理说明
- 迭代器提供顺序输入:我们创建了一个包含两个元素的迭代器
input_sequence,第一个元素是覆盖询问的回答"n",第二个是新文件名new_filename。 - 动态返回输入值:用lambda函数包裹
next(input_sequence),每次input函数被调用时,会自动从迭代器中取出下一个值。这样:- 第一次调用
input(询问是否覆盖文件)时,返回"n"; - 第二次调用
input(要求输入新文件名)时,返回new_filename。
- 第一次调用
- 避免覆盖问题:只需要一次
monkeypatch.setattr调用,就可以按顺序模拟多次不同的输入,不会出现之前的覆盖或值错位问题。
如果后续需要模拟更多次input调用,只需要在input_sequence中添加对应的元素即可,这个方案的扩展性非常好。
内容的提问来源于stack exchange,提问作者Uwe Schweinsberg
相关产品推荐
相关产品推荐

