模拟Java输入流

模拟Java输入流,java,mocking,Java,Mocking,请提供指针来帮助我模拟java InputStream对象。 这是我想要模仿的代码行: InputStreamReader inputData = new InputStreamReader(System.in); bufferdReader = new BufferedReader(inputData); bufferdReader.readLine(); 您可以使用一个测试工具并用您的测试数据填充它 @Brad在评论中的例子: InputStream anyInputStream = n

请提供指针来帮助我模拟java InputStream对象。 这是我想要模仿的代码行:

InputStreamReader inputData = new InputStreamReader(System.in);
bufferdReader = new BufferedReader(inputData);
bufferdReader.readLine(); 
您可以使用一个测试工具并用您的测试数据填充它

@Brad在评论中的例子:

InputStream anyInputStream = new ByteArrayInputStream("test data".getBytes());
您可以使用创建一些存根输入流:

InputStream stubInputStream = 
     IOUtils.toInputStream("some test data for my input stream", "UTF-8");

更改您的对象以便更容易测试,如下所示:

public MyObject {
    private InputStream inputStream;

    public void setInputStream(InputStream inputStream) {this.inputStream = inputStream;}

    public void whatever() {
        InputStreamReader inputData = new InputStreamReader(inputStream);
        bufferdReader = new BufferedReader(inputData);
        bufferdReader.readLine(); 
    }
}
然后,当您使用对象时,首先初始化其inputStream:

MyObject myObject = new MyObject();
myObject.setInputStream(System.in);

现在您有了一个对象,可以使用您想要的InputStream的任何实现来测试它(ByteArrayInputStream是一个很好的尝试)。

我不同意这个问题的选择答案。嘲笑Mockito这样的框架是不错的,但是当标准java API可用时,你可以考虑使用它。p> i、 e

既然可以使用真实对象及其所有状态和行为,为什么还要在测试类中使用模拟对象呢


要了解更多这方面的工作原理,您可以查看“decorator”设计模式。

假设您使用的是Maven,您可以将资源放入“src/test/resources/”文件夹,比如“src/test/resources/Wonder mock data.xml”。然后在jUnit中,您可以执行以下操作:

    String resourceInputFile = "/database-insert-test.xml";
    URL url = this.getClass().getResource(resourceInputFile);
    Assert.assertNotNull("Can't find resource " + resourceInputFile, url);

    InputStream inputStream = url.openStream();

    // Now you can just use the inputStream for method calls requiring this param
    (...)

在本例中,如果在当前类路径中找不到给定的资源,url变量将为null。此方法允许您在不同的resourceInputFile中放置多个场景。。。还请记住,“src/test/resources/”下的所有资源(不仅仅是xml文件,任何类型如txt、html、jpeg等)通常都可以作为来自所有jUnit测试的类路径资源使用。

我发现的最佳解决方案是使用

@Test
    public void testReadFile() {
    TestClass ClassName = Mockito.mock(TestClass.class);
     InputStream in = Mockito.mock(InputStream.class);
     InputStreamReader inr =Mockito.mock(InputStreamReader.class);
     BufferedReader bufferedReader =Mockito.mock(BufferedReader.class);
       try {
         PowerMockito.whenNew(InputStreamReader.class).withArguments(in).thenReturn(inr);
         PowerMockito.whenNew(BufferedReader.class).withArguments(inr).thenReturn(bufferedReader);
         String line1 = "example line";
         PowerMockito.when(bufferedReader.readLine()).thenReturn(line1).thenReturn(null);
         method return type = Whitebox.invokeMethod(ClassName, "MethodName", arguement);
         assertEquals("result is::","expected", actual);
     } catch (Exception e) {
         e.printStackTrace();
     }
 }
final InputStream inputStream1 = IOUtils.toInputStream("yourdata");
然后在(imageService.saveOrUpdate(Matchers.anyObject()))时,将inpustream包装在bufferedReader中,这是围绕输入流编写测试的最佳方法;
String testString = "test\nstring";
InputStream stream = new ByteArrayInputStream(testString.getBytes(StandardCharsets.UTF_8));

BufferedReader reader = new BufferedReader(new InputStreamReader(stream));

Assert.assertEquals("test", reader.readLine());
Assert.assertEquals("string", reader.readLine());

参考

您的问题是否在系统中?您可能希望重构代码,以便传递另一个InputStream,而不是System.in;然后,您可以使用任何模拟框架(如答案中提到的)来模拟此InputStream。感谢您的快速回复。。将检查I如何导入
客户端
?很抱歉,我是mockito和junit的新手,您正在这一行使用客户端:
org.junit.Assert.when(新客户端(bufferedReader.parseLine())
Client是一个类,它使用缓冲读取器逐行读取并解析ITI如果您想多次使用流,使用后如何重置它?可以将其包装在BufferedInputStream中,并使用mark()和reset()。但是在设置方法中实例化一个新的字符集可能更容易(假设我们还在这里讨论测试)。从v2.3开始,您需要添加字符集,例如:
toInputStream(“someString”,“UTF-8”)
。不推荐使用仅以字符串作为参数的版本。谢谢@JonyD!我更新了答案以包含charset参数。我最喜欢的答案!我想补充的是,您可以使用
StandardCharsets.UTF_8
,而不是使用非类型安全字符串。这里有一个用例:模拟多个不同的调用,例如在一个循环中(错误的input1->错误的input2->正确的input3)。将InputStream代码和读取器代码放在不同的类中,就像java api那样。让您的测试类通过Reader的实现,而不是InputStream,在生产代码中,也将Reader的实现传递给正在读取数据/进行数据处理的类。另外的好处是
ByteArrayInputStream
支持
mark()
reset()
Nice和simple
InputStream anyInputStream=newbytearrayinputstream(“测试数据”.getBytes()):
val-inputStream=“test-data”。byteInputStream()
这增加了对IOUtils的另一种依赖,这使测试代码更大。不是我们希望从小型单元测试中获得的预期效果。。。
final InputStream inputStream1 = IOUtils.toInputStream("yourdata");
String testString = "test\nstring";
InputStream stream = new ByteArrayInputStream(testString.getBytes(StandardCharsets.UTF_8));

BufferedReader reader = new BufferedReader(new InputStreamReader(stream));

Assert.assertEquals("test", reader.readLine());
Assert.assertEquals("string", reader.readLine());
when(imageService.saveOrUpdate(Matchers.<Image>anyObject())).thenReturn(image);