专栏首页软件测试那些事跨层单元测试de歪门邪道

跨层单元测试de歪门邪道

一般来说,Spring应用的单元测试都是发生在该应用的某个层,例如controller、service或者是dao层。 而service层既是应用服务的主要实现者,也是重点被测试的对象,其余各层,如controller层一般以线性代码为主,缺少业务逻辑,可以少测甚至是不测。 不过也有些团队会认为,既然应用的入口是controller,那么从controller层入口对服务进行测试,更贴合用户的场景,这部分的测试也更有业务价值,也更能提升对产品质量的信心。如果某些测试场景或者分支是通过controller层无法达到的,那么这部分的测试优先级就可以降低。 因此,笔者就见到过controller连同service一起进行测试的场景,也就是所谓的跨层单元测试 还是以TestLink4J为例,有如下用例

package com.testlink4j.controller;
//import 
@Slf4j
public class KeywordsControllerServiceTest {

        @InjectMocks
        private KeywordsServiceImpl keywordsService;

        @InjectMocks
        KeywordsRestController keywordsRestController;

        @Mock
        KeywordsMapper keywordsMapper;
        @BeforeEach()
        public void setup() {
            MockitoAnnotations.initMocks(this);
            ReflectionTestUtils.setField(keywordsRestController,
"keywordsService",keywordsService);
        }


  @Test
  public void CreateKeywordsSuccessfullyTest() {
      Keywords keywords=Keywords.builder().id(666).keyword("tester")
.testproject_id(333).notes("tester").build();
      Mockito.when(keywordsMapper.selectByPrimaryKey(1)).thenReturn(keywords);
      Keywords responseString=keywordsRestController.findKeywordById(1);
      log.info(JSON.toJSONString(responseString));
            assertThatJson(responseString).isEqualTo(keywords);
  }

}

用例调用了keywordsRestController.findKeywordById方法,并验证其返回结果,实现了对keywordsRestController和keywordsService的测试,也就是controller和service两层的测试。 以下是执行的日志:

22:01:36.569 [main] DEBUG org.springframework.test.util.ReflectionTestUtils - Setting field 'keywordsService' of type [null] on target object [com.testlink4j.controller.KeywordsRestController@422c3c7a] or target class [class com.testlink4j.controller.KeywordsRestController] to value [com.testlink4j.service.impl.KeywordsServiceImpl@18230356]
22:01:36.747 [main] INFO com.testlink4j.controller.KeywordsControllerServiceTest - {"id":666,"keyword":"tester","notes":"tester","testproject_id":333}


这其中的运行逻辑是这样的

  1. 首先对keywordsMapper进行mock
  2. 将被mock的keywordsMapper注入到keywordsService
  3. 将keywordsService再注入到keywordsRestController(此处要用到歪门邪道哦),从而完成被测对象的实例化
  4. 利用Mockito准备测试桩
  5. 执行用例并验证结果

简单介绍一下案例中的代码是如何实现上述逻辑的,

  1. 使用@InjectMocks分别对Service和Controller进行注解,从而利用来实现这两个对象的实例化。不是使用@Autowired等方式以Spring容器托管的方式来实现被测对象的实例化,这其中也利用了@InjectMocks在mock注入时的slient injection特性,也就是注入失败时不会抛出异常,而是使用默认值(此时keywordsRestController中的keywordsService为null),而Spring容器在实例化bean如果遇到错误,则会抛出异常,导致用例无法执行。
  2. 通过ReflectionTestUtils这个Spring提供的反射注入工具,将@InjectMocks提供的keywordsService实例注入到keywordsRestController中名为keywordsService的变量中。这样,当测试用例调用keywordsRestController的接口时,就可以顺利执行并调用keywordsService的方法了,从而触发了测试桩完成测试。 3)一定是先实例化被测对象,然后再注入哦。 这2行代码的顺序一定不能反了
MockitoAnnotations.initMocks(this); 
ReflectionTestUtils.setField(keywordsRestController,
"keywordsService",keywordsService);

本文分享自微信公众号 - 软件测试那些事(antony-not-available),作者:风月同天测试人

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-11-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用junit5编写一个类似ZeroCode的测试框架1

    最近笔者在尝试基于应用日志来自动生成测试用例。这其中就需要一个配套的简易测试框架。梳理了一下,其中的技术点有: 0.使用csv文件来定义测试用例及步骤 1.使用...

    Antony
  • 去中心化的测试用例平台之Maven插件

    从测试用例管理的角度来看,测试平台或者测试框架,首先需要解决业务域的问题 1)如何来表征一个测试用例、步骤以及用例集 2)如何来执行用例、用例集 3)如何来获取...

    Antony
  • 在家隔离,不忘学习-FizzBuzz-TDD

    在之前的的TDD案例-FizzBuzz文章中,我们介绍了如何以TDD的方式,通过5个测试用例,来驱动我们实现了FizzBuzz。 本文将继续对FizzBuzz的...

    Antony
  • [Linux][mm]watermark_scale_factor的调整以及遇到的问题

    在较高的Linux版本上,支持了watermark_scale_factor参数(完整路径/proc/sys/vm/watermark_scale_factor...

    皮振伟
  • 一文读懂云计算,所有常用术语

    云计算:云计算指的是交付计算即服务(或者交付结果中包括计算架构),而不是产品。资源共享,软件和信息通过网络(企业内网、互联网或者二者的结合)供计算机或者其他设备...

    企鹅号小编
  • 机器学习中有哪些形式简单却很巧妙的 idea?

    作者:桔了个仔 https://www.zhihu.com/question/347847220/answer/836019446

    Datawhale
  • 懒人的小技巧, 批处理修改IP

    FlyLolo
  • iOS多边形马赛克的实现(下)

    上一篇里我们详述了多边形马赛克的实现步骤,末尾提出了一个思考:如何在涂抹时让马赛克逐块显示呢? 再回顾一下多边形马赛克的实现。首先进行图片预处理,将原图转成bi...

    天天P图攻城狮
  • iOS多边形马赛克的实现(上)

    马赛克(英语:Mosaic)是镶嵌艺术的音译,原本是指一种装饰艺术,通常使用许多小石块或有色玻璃碎片拼成图案,在教堂中的玻璃艺品,又称为花窗玻璃(stained...

    天天P图攻城狮
  • Spark on Kubernetes在Mac的Demo

    讲真,Spark 2.3 开始原生支持 K8S,按照Spark 2.4 官网的方法一开始真的没跑起来,K8S Dashboard 又一堆问题,可能我太菜了,头疼...

    runzhliu

扫码关注云+社区

领取腾讯云代金券