单元测试1 文件流单元测试

单元测试1 文件流单元测试

书写文件处理函数的时候,最好输入输出写为流文件或者File格式,这样方便mock

File类型的单元测试

  1. File类在创建的时候不会验证路径的有效性,因此可以随便new一个File类
File file = new File("abc.txt");

当单元测试读进去之后,只有名字 ”abc.txt" 是存在的,但是后续处理过程中就会报

java.io.FileNotFoundException: xxx.xxx(系统找不到指定文件的异常)
  1. 也可以使用PowerMockito来mock一个虚拟File

PowerMockito使用时需要引入maven依赖

<dependency>
    <groupId>org.powermockgroupId>
    <artifactId>powermock-module-junit4artifactId>
    <version>2.0.0version>
    <scope>testscope>
dependency>
<dependency>
    <groupId>org.powermockgroupId>
    <artifactId>powermock-api-mockito2artifactId>
    <version>2.0.0version>
    <scope>testscope>
dependency>
public class ParserTest {
@Test
   public final void testParse() {
      File MOCKEDFILE = PowerMockito.mock(File.class);
      PowerMockito.when(MOCKEDFILE.exists()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.isFile()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.isDirectory()).thenReturn(false);
      PowerMockito.when(MOCKEDFILE.createNewFile()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.length()).thenReturn(11111111L);
//what about the path of MOCKEDFILE which isn't existing
      PowerMockito.when(MOCKEDFILE.getPath()).thenReturn(?????);
   }

FileInputStream类型的单元测试

1.FileInputStream流概念

FileInputStream流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等

2.构造方法

2.1 通过打开与File类对象代表的实际文件的链接来创建FileInputStream流对象

public FileInputStream(File file) throws FileNotFoundException{}

若File类对象的所代表的文件不存在;不是文件是目录;或者其他原因不能打开的话,则会抛出

java.io.FileNotFoundException: xxx.xxx(系统找不到指定文件的异常)

2.2 通过指定的字符串参数来创建File类对象,而后再与File对象所代表的实际路径建立链接创建FileInputStream流对象

public FileInputStream(String name) throws FileNotFoundException

实际上源码是先将name转换为file类,然后在读取为FileInputStream对象

 public FileInputStream(String name) throws FileNotFoundException {
 	this(name != null ? new File(name) : null);
 }

2.3 通过FileDecscriptor文件描述符来作为参数,文件描述符是指与计算机系统中的文件的连接,前面两个方法的源码中最后都是利用文件描述符来建立连接的(设计计算机系统,暂时不理解)

public FileInputStream(FileDescriptor fdObj) 

3.单元测试

当在函数里面用到FileInputStream的时候可以使用

@PrepareForTest(Parser.class)
public class ParserTest {
@Test
   public final void testParse() {
      File MOCKEDFILE = PowerMockito.mock(File.class);
      PowerMockito.when(MOCKEDFILE.exists()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.isFile()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.isDirectory()).thenReturn(false);
      PowerMockito.when(MOCKEDFILE.createNewFile()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.length()).thenReturn(11111111L);
//what about the path of MOCKEDFILE which isn't existing
      PowerMockito.when(MOCKEDFILE.getPath()).thenReturn(?????);
//how to assign a File an FileInputStream? (I thought something like)
      PowerMockito.mockStatic(FileInputStream.class);
      FileInputStream MOCKEDINPUTSTREAM = PowerMockito.mock(FileInputStream.class);
      PowerMockito.whenNew(FileInputStream.class).withArguments(File.class).thenReturn(MOCKEDINPUTSTREAM);
//how to mock the private method readMyStream
   }

@PrepareForTest(Class1.class)是必须的,否则

PowerMockito.whenNew(FileInputStream.class).withArguments(File.class).thenReturn(MOCKEDINPUTSTREAM);

不能代替构造器创建新的FileInputStream。

回答:https://stackoverflow.com/questions/51205275/how-to-mock-fileinputstream-with-powermock

相似的流类型(exp:FileOutputStram,ZipOutputStream之类的都可以使用相同方法来实现)

不过有时候会不起作用,具体原因没找到,改着改着就好了,但不是@PrepareForTest的原因,后续遇到继续总结

示例:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class InputStreamClassDemo {
    public void demo1(File file) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] b=new byte[(int) file.length()];
        fileInputStream.read(b);
        fileInputStream.close();
        System.out.println(new String(b));
    }
}
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import static org.junit.Assert.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest({InputStreamClassDemo.class})
public class InputStreamClassDemoTest {

    @InjectMocks
    InputStreamClassDemo inputStreamClassDemo;
    @Test
    public void demo1() throws Exception {
        File file = PowerMockito.mock(File.class);
        PowerMockito.when(file.length()).thenReturn(3L);
        FileInputStream mock = PowerMockito.mock(FileInputStream.class);
        PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenReturn(mock);
        inputStreamClassDemo.demo1(file);
    }
}

你可能感兴趣的:(单元测试汇总,单元测试,java)