Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何模拟pyunit的标准输入?_Python_Linux_Python Unittest - Fatal编程技术网

Python 如何模拟pyunit的标准输入?

Python 如何模拟pyunit的标准输入?,python,linux,python-unittest,Python,Linux,Python Unittest,我正在尝试测试一个函数,该函数从stdin获取输入,我目前正在使用类似以下内容进行测试: cat /usr/share/dict/words | ./spellchecker.py import sys def check_stdin(): # some code that uses sys.stdin 在测试自动化的名义下,pyunit是否有任何方法可以将假输入到raw\u input()?简单的答案是raw\u input() 答案中有一些很好的例子 下面是一个简单的小示例,它使用

我正在尝试测试一个函数,该函数从
stdin
获取输入,我目前正在使用类似以下内容进行测试:

cat /usr/share/dict/words | ./spellchecker.py
import sys

def check_stdin():
  # some code that uses sys.stdin
在测试自动化的名义下,
pyunit
是否有任何方法可以将假输入到
raw\u input()

简单的答案是
raw\u input()

答案中有一些很好的例子

下面是一个简单的小示例,它使用
lambda
,丢弃提示并返回我们想要的内容

测试中的系统 测试用例: 更新--使用unittest.mock.patch 自从Python3.3以来,
unittest
有一个名为mock的新子模块,它完全满足您的需要。对于使用Python2.6或更高版本的用户,可以找到
mock
的后端口

上一个答案--替换sys.stdin 我想sys模块可能就是你要找的

你可以这样做

import sys

# save actual stdin in case we need it again later
stdin = sys.stdin

sys.stdin = open('simulatedInput.txt','r') 
# or whatever else you want to provide the input eg. StringIO
无论何时调用,原始输入都将从simulatedInput.txt读取。如果simulatedInput的内容为

hello
bob

然后,对原始输入的第一个调用将返回“hello”,第二个“bob”和第三个调用将抛出一个EOFError,因为没有更多的文本可读取。

sys.stdin
替换为
StringIO
的实例,并将通过
sys.stdin
返回的数据加载到
StringIO
实例中。另外,
sys.stdin\uuuuuuu
包含原始的
sys.stdin
对象,因此在测试后恢复
sys.stdin
非常简单,只需
sys.stdin=sys.\uuuuuuu stdin\uuuu


是一个很棒的python模拟模块,具有方便的修饰符,可以像这样为您进行修补,并具有自动清理功能。你应该去看看。

你没有在
拼写检查器.py
中描述什么类型的代码,这让我可以自由推测

假设是这样的:

cat /usr/share/dict/words | ./spellchecker.py
import sys

def check_stdin():
  # some code that uses sys.stdin
为了提高
check_stdin
函数的可测试性,我建议对其进行如下重构:

def check_stdin():
  return check(sys.stdin)

def check(input_stream):
  # same as original code, but instead of
  # sys.stdin it is written it terms of input_stream.
现在,您的大部分逻辑都在
check
函数中,您可以手工制作任何可以想象的输入,以便正确地测试它,而无需处理
stdin

我的2美分。

如果您正在使用(由Michael Foord编写),为了模拟原始输入功能,您可以使用如下语法:

@patch('src.main.raw_input', create=True, new=MagicMock(return_value='y'))
def test_1(self):
    method_we_try_to_test();    # method or function that calls **raw_input**

您可能想尝试为依赖注入构建应用程序,就像在回答类似问题时一样。;-)(应该是
/spellchecker.py
)单元测试不应该访问文件系统。@Johnsyweb为什么不?介意详细说明并启发我吗?那么,我如何测试文件操纵功能,使用
stringIO
而不是真正的文件会更好吗?如果是,如何测试?(除了速度比磁盘IO快之外,数据迟早会从磁盘上出来,这是yuo将测试数据与测试代码分离的一种方式。@ted:你说的代码与数据分离的观点很好,但你的问题很难笼统地回答(特别是在其他人回答的评论中。我建议将此作为一个新问题提问。
sys.stdin
open()
返回的流不完全相同。例如,如果您的代码是
stream.tell())
,则它将在本测试中起作用,但不适用于真正的
sys.stdin
。如果您必须使用monkey patch
sys.stdin
,则很可能您正在尝试“单元测试”太多了。关于FuKy,也考虑了它的好处。抱歉,代码< > NAMEXGETTER。RWYOPEN输入/代码>定义在<代码> NAMEGETTER < /代码>?@ ALPER,它不是。
@patch('src.main.raw_input', create=True, new=MagicMock(return_value='y'))
def test_1(self):
    method_we_try_to_test();    # method or function that calls **raw_input**