Mock 测试导出Excel文件

业务经常涉及到Excel文件的导出,后台给前端提供导出服务接口,不可能自己都没测试过,就提供给前端调用。最好的方案就是程序员编写单元测试,可以说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。

##单元测试
java 常用的单元测试框架是Junit,利用测试框架可以使我们在编写测试用例的过程更加便捷优雅。通过测试用例,我们只需要关注:对于特定的输入,被测对象的返回是否征程,下面是涉及到的相关类。

controller类提供导出接口

    @GET
        @Path("/{version}/exportRecordDetail")
        @ApiOperation(value = "导出电子支付结算明细")
        public String exportRecordDetail (@Context HttpServletResponse response, @BeanParam SingleWithdrawReq request){        
            //...
            response.setContentType("application/x-download");
            // 获取模板文件
            String templateFile = "/export/AccountRecordDetail.xlsx";	    
            try (InputStream is = this.getClass().getResourceAsStream(templateFile);
                 OPCPackage pkg = OPCPackage.open(is);
                 XSSFWorkbook workbook = new XSSFWorkbook(pkg)) {
                outputFile = URLEncoder.encode(outputFile, "UTF-8");        
                //...
                workbook.write(response.getOutputStream());
            } catch (IOException | InvalidFormatException e) {
                //... 
            }
            return null;
        }

核心代码: workbook.write(response.getOutputStream()); 这一句是指将文件写到输出流里,用到了HttpservletResponse 接口,因此在测试用例里,我们并不能直接实例化HttpservletResponse,因而也就不能作为参数传递到controller层。

那怎么办呢?首先想到了引入mock方法。Mock的引入,可以帮助我们构建比较难构造的Object,这些Object 通常有很多以来,在单元测试中构造出这些对象通常花费比较大的成本。

Mock 单元测试

@Test 
public void exportService() {
    SingleWithdrawReq request = new SingleWithdrawReq();
    request.setParkId(12345);
    ParkingBalanceAccountResources resource = new ParkingBalanceAccountResources();
    // Mock HttpServletResponse 实例
    HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
    // 定义一个输出的本地文件
    File file = new File("output.xls");
    try (ServletOutputStream sos = new MockServletOutputStreamUtil (file)) {
        //用MockServletOutputStreamUtil 代替ServletOutputStream
        Mockito.when(response.getOutputStream()).thenReturn(sos);
        resource.exportRecordDetail(response, request);
    }
 }

单元测试思路: 将输出流写到一个临时文件里,但是在case里我们如何传入一个response并且得到输出流呢?

##工具类:构造ServletOutputStream

public class MockServletOutputStreamUtil extends ServletOutputStream {

    private FileOutputStream fos;    //定义文件输出流
    public MockServletOutputStreamUtil(File file) {
        try {
            this.fos = new FileOutputStream(file);    // 将输出流指向文件
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public boolean isReady() {
        return true;
    }
    @Override
    public void setWriteListener(WriteListener writeListener) {
        throw new RuntimeException("do not support this method");
    }
    @Override
    public void write(int b) throws IOException {
        fos.write(b);
    }
    @Override
    public void close() {
        try {
            fos.close();
        } catch (IOException e) {
            throw new RuntimeE
xception(e);
        }
    }

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在Java中,Mock测试是一种常见的测试方法,用于模拟对象或服务器的行为,以便进行自己想要的测试Mock测试主要有两种场景。 第一种场景是Mock一个对象,通过写入预期的值来进行测试。这种方法主要适用于单元测试,即针对特定语言开发的程序,必须使用基于该语言的Mock方案来实现。例如,Mockito是一种针对Java的Mock框架,适用于单元测试。\[1\] 第二种场景是Mock一个服务器,构造一个虚假的服务来返回预期的结果,以进行测试。这种方法主要适用于接口测试和性能测试Mock方案与程序使用的语言无关,可以使用Java、Python等语言来实现。例如,可以搭建一个Mock服务器来模拟接口的行为,适用范围没有限制。\[2\] 在Java中进行Mock测试时,可以使用一些框架和注解来简化测试代码的编写。例如,使用Mockito框架可以使用注解@RunWith(MockitoJUnitRunner.class)和@Mock来模拟对象的行为,使用@InjectMocks来注入被测试对象。下面是一个示例代码: ```java @RunWith(MockitoJUnitRunner.class) @PrepareForTest(MyService.class) public class UserServiceTest { @InjectMocks private MyService myService; @Mock private MyRepository myRepository; @Mock private YourRepository yourRepository; @Test public void testInjectMocks() { System.out.println(myService.getMyRepository().getClass()); } } ``` 在这个示例中,使用了@RunWith(MockitoJUnitRunner.class)注解来运行测试,并使用@Mock注解来模拟对象的行为。@InjectMocks注解用于注入被测试对象。\[3\] 总结起来,Java中的Mock测试是一种常见的测试方法,可以用于模拟对象或服务器的行为,以进行自己想要的测试。可以使用Mockito等框架和注解来简化测试代码的编写。 #### 引用[.reference_title] - *1* *2* [走进Java接口测试Mock(概念篇)](https://blog.csdn.net/zuozewei/article/details/84892008)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [JAVA测试类注解以及Mock测试](https://blog.csdn.net/m0_67793822/article/details/127387243)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值