《Java单元测试实战》——案例集锦:Java单元测试典型案例集锦(6)

简介: 《Java单元测试实战》——案例集锦:Java单元测试典型案例集锦(6)

《Java单元测试实战》——案例集锦:Java单元测试典型案例集锦(5) https://developer.aliyun.com/article/1232054?groupCode=java



六、 如何测试链式调用


在日常编码过程中,很多人都喜欢使用链式调用,这样可以让代码变得更简洁。

 

 

 

1. 案例代码

 

这里,通过修改后的添加跨域支持代码来举例说明(原方法没有返回值)。


image.png

2. 方法1:普通测试法(不推荐)

 

正常情况下,每一个依赖对象及其调用方法都要mock,编写的代码如下:


/**
 * 跨域辅助测试类
 */
public class CorsHelperTest {
    /**
     * 测试: 添加跨域支持
     */
    @Test
    public void testAddCorsMapping() {
        // 模拟依赖方法
        CorsRegistry registry = Mockito.mock(CorsRegistry.class);
        CorsRegistration registration = Mockito.mock(CorsRegistration.class);
        Mockito.doReturn(registration).when(registry).addMapping(Mockito.anyString());
        Mockito.doReturn(registration).when(registration).allowedOrigins(Mockito.any());
        Mockito.doReturn(registration).when(registration).allowedMethods(Mockito.any());
        Mockito.doReturn(registration).when(registration).allowCredentials(Mockito.anyBoolean());
        Mockito.doReturn(registration).when(registration).maxAge(Mockito.anyLong());
        Mockito.doReturn(registration).when(registration).allowedHeaders(Mockito.any());
        // 调用测试方法
        Assert.assertEquals("跨域注册不一致", registration, CorsHelper.addCorsMapping(registry));
        // 验证依赖方法
        Mockito.verify(registry).addMapping("/**");
        Mockito.verify(registration).allowedOrigins("*");
        Mockito.verify(registration).allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS");
        Mockito.verify(registration).allowCredentials(true);
        Mockito.verify(registration).maxAge(3600L);
        Mockito.verify(registration).allowedHeaders("*");
    }
}

3. 方法2:利用RETURNS_DEEP_STUBS参数法(推荐)

 

对于链式调用,Mockito提供了更加简便的单元测试方法——提供Mockito.RETURNS_DEEP_STUBS参数,实现链式调用返回对象的自动mock。利用Mockito.RETURNS_DEEP_STUBS参数编写的测试用例如下:


/**
 * 跨域辅助测试类
 */
public class CorsHelperTest {
    /**
     * 测试: 添加跨域支持
     */
    @Test
    public void testAddCorsMapping() {
        // 模拟依赖方法
        CorsRegistry registry = Mockito.mock(CorsRegistry.class, Answers.RETURNS_DEEP_STUBS);
        CorsRegistration registration = Mockito.mock(CorsRegistration.class);
        Mockito.when(registry.addMapping(Mockito.anyString())
            .allowedOrigins(Mockito.any())
            .allowedMethods(Mockito.any())
            .allowCredentials(Mockito.anyBoolean())
            .maxAge(Mockito.anyLong())
            .allowedHeaders(Mockito.any()))
            .thenReturn(registration);
        // 调用测试方法
        Assert.assertEquals("跨域注册不一致", registration, CorsHelper.addCorsMapping(registry));
        // 验证依赖方法
        Mockito.verify(registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
            .allowCredentials(true)
            .maxAge(3600L))
            .allowedHeaders("*");
    }
}

 

代码说明:

 

在mock对象时,需要指定Mockito.RETURNS_DEEP_STUBS参数;

在mock方法时,采用when-then模式,when内容是链式调用,then内容是返回的值;

在verify方法时,只需要验证最后1次方法调用,verify内容是前n次链式调用;如果验证时某个方法调用的某个参数指定错误时,最后一个方法调用验证将因为这个mock对象没有方法调用而抛出异常。

 

4. 方法3:利用RETURNS_SELF参数法(推荐)

 

对于相同返回值的链式调用,Mockito提供了更加简便的单元测试方法——提供Mockito.RETURNS_SELF参数,实现链式调用返回对象的自动mock,而且还能返回同一mock对象。利用Mockito.RETURNS_SELF参数编写的测试用例如下:


image.png

代码说明:

 

在mock对象时,对于自返回对象,需要指定Mockito.RETURNS_SELF参数;

在mock方法时,无需对自返回对象进行mock方法,因为框架已经mock方法返回了自身;

在verify方法时,可以像普通测试法一样优美地验证所有方法调用。

 

方法对比:

 

普通测试法:mock调用方法语句较多;

利用RETURNS_DEEP_STUBS参数法:mock调用方法语句较少,适合于链式调用返回不同值;

利用RETURNS_SELF参数法:mock调用方法语句最少,适合于链式调用返回相同值。



《Java单元测试实战》——案例集锦:Java单元测试典型案例集锦(7) https://developer.aliyun.com/article/1232052?groupCode=java

相关文章
|
2小时前
|
Java 测试技术 数据库
【JAVA基础篇教学】第十七篇:Java单元测试
【JAVA基础篇教学】第十七篇:Java单元测试
|
2小时前
|
Web App开发 JavaScript 前端开发
《手把手教你》系列技巧篇(三十九)-java+ selenium自动化测试-JavaScript的调用执行-上篇(详解教程)
【5月更文挑战第3天】本文介绍了如何在Web自动化测试中使用JavaScript执行器(JavascriptExecutor)来完成Selenium API无法处理的任务。首先,需要将WebDriver转换为JavascriptExecutor对象,然后通过executeScript方法执行JavaScript代码。示例用法包括设置JS代码字符串并调用executeScript。文章提供了两个实战场景:一是当时间插件限制输入时,用JS去除元素的readonly属性;二是处理需滚动才能显示的元素,利用JS滚动页面。还给出了一个滚动到底部的代码示例,并提供了详细步骤和解释。
30 10
|
2小时前
|
前端开发 测试技术 数据安全/隐私保护
软件测试 —— 案例系统缺陷报告
软件测试 —— 案例系统缺陷报告
6 1
|
2小时前
|
监控 数据可视化 IDE
python自动化测试实战 —— 单元测试框架
python自动化测试实战 —— 单元测试框架
9 2
|
2小时前
|
Web App开发 JavaScript 前端开发
《手把手教你》系列技巧篇(四十三)-java+ selenium自动化测试-处理https 安全问题或者非信任站点-上篇(详解教程)
【5月更文挑战第7天】本文介绍了如何在Java+Selenium自动化测试中处理浏览器对不信任证书的处理方法,特别是针对IE、Chrome和Firefox浏览器。在某些情况下,访问HTTPS网站时会遇到证书不可信的警告,但可以通过编程方式跳过这些警告。
13 1
|
2小时前
|
前端开发 Java 测试技术
《手把手教你》系列技巧篇(四十二)-java+ selenium自动化测试 - 处理iframe -下篇(详解教程)
【5月更文挑战第6天】本文介绍了如何使用Selenium处理含有iframe的网页。作者首先解释了iframe是什么,即HTML中的一个框架,用于在一个页面中嵌入另一个页面。接着,通过一个实战例子展示了在QQ邮箱登录页面中,由于输入框存在于iframe内,导致直接定位元素失败。作者提供了三种方法来处理这种情况:1)通过id或name属性切换到iframe;2)使用webElement对象切换;3)通过索引切换。最后,给出了相应的Java代码示例,并提醒读者根据iframe的实际情况选择合适的方法进行切换和元素定位。
8 0
|
2小时前
|
前端开发 测试技术 Python
《手把手教你》系列技巧篇(四十一)-java+ selenium自动化测试 - 处理iframe -上篇(详解教程)
【5月更文挑战第5天】本文介绍了HTML中的`iframe`标签,它用于在网页中嵌套其他网页。`iframe`常用于加载外部内容或网站的某个部分,以实现页面美观。文章还讲述了使用Selenium自动化测试时如何处理`iframe`,通过`switchTo().frame()`方法进入`iframe`,完成相应操作,然后使用`switchTo().defaultContent()`返回主窗口。此外,文章提供了一个包含`iframe`的HTML代码示例,并给出了一个简单的自动化测试代码实战,演示了如何在`iframe`中输入文本。
15 3
|
2小时前
|
JavaScript 前端开发 Java
《手把手教你》系列技巧篇(四十)-java+ selenium自动化测试-JavaScript的调用执行-下篇(详解教程)
【5月更文挑战第4天】本文介绍了如何使用JavaScriptExecutor在自动化测试中实现元素高亮显示。通过创建并执行JS代码,可以改变元素的样式,例如设置背景色和边框,以突出显示被操作的元素。文中提供了一个Java示例,展示了如何在Selenium中使用此方法,并附有代码截图和运行效果展示。该技术有助于跟踪和理解测试过程中的元素交互。
9 0
|
2小时前
|
测试技术
测试基础 Junit单元测试框架
测试基础 Junit单元测试框架
12 2
测试基础 Junit单元测试框架
|
2小时前
|
Java 测试技术 持续交付
Java测试驱动开发实践指南
Java测试驱动开发实践指南
13 0