赞
踩
为了保证代码质量,在写完代码后,写单测是很有必要的。当然,在大部分情况下,我们可能不会写单测,而是直接把应用部署起来,直接自测,然后再联调。估计很大一部分人,都是用这种方式开发。当然,我之前也是按这个方式来开发,单测覆盖率纯粹是为了满足公司的指标要求,大部分流于形式。
慢慢的,我感受到写单测带来的几个好处:
启动一个应用,几分钟,找bug,修bug,再重启应用。这个过程不断的重复,应用重启太浪费时间。而单测不需要重启整个应用,只对几个service做测试,效率高很多
单测可以对代码运行中的各种情况进行模拟,并对最终的返回结果断言,这是自己自测很难模拟的。而且,这些单测,是沉淀的资产。下次修改代码,可以重跑以前单测,发现问题,避免踩坑。
我们很容易对单测产生误解,所以这里我先把2个概念说明一下:
测试过程中,会启动整个Spring容器,调用DB 或者 依赖的外部接口等。只不过访问的环境是测试环境。这个过程最大程度还原生产环境过程,但是耗时长。
不启动整个应用,只对单个接口/类进行测试。不调用DB 、外部接口,依赖的服务都Mock掉,只测试代码逻辑。这个过程,测试用例耗时短。
我们说的单测,是指第2种。
单测过程分2步,第一步:Mock外部依赖,第二步:断言
Mock框架很多,我以比较熟悉的Mockito为例,介绍单测的基本过程
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>3.3.3</version>
- <scope>test</scope>
- </dependency>
- @Service
- public class ServiceA{
- @Resource
- private DaoA daoA;
-
- @Resource
- private ServiceC serviceC;
-
-
- }
@Mock private ServiceA serviceA;
这种方式,serviceA中的所有方法都会被mock,并不会真正被调用到
ServiceA 依赖了 ServiceC 和 DaoA,使用InjectMocks可以自动注入
@InjectMocks private ServiceA serviceA;
@Spy private ServiceC serviceC;
这种方式,调用serviceC的方法,会被真实调用
doNothing().when(serviceA).save(any(AbnormalTask.class));
Mockito.when(serviceA.getItem(any(AAA.class))).thenAnswer(invocationOnMock -> { return xxx; });
try (MockedStatic<IdGenerator> utilities = Mockito.mockStatic(IdGenerator.class)) { utilities.when(() -> IdGenerator.generate(null)).thenReturn("1"); FulfillSingleResult<Object> fulfillSingleResult = serviceA.executeTask(taskExecuteRequest); assertTrue(fulfillSingleResult.isSuccess()); }
需要注意的是,断言的内容需要写到try{} 代码块内部,否则会不生效。
assertTrue(fulfillSingleResult.isSuccess());assertFalse(xxx);
@Rule public ExpectedException thrown = ExpectedException.none();thrown.expectMessage("xxx异常");
-
-
- @RunWith(MockitoJUnitRunner.class)
- public class ServiceATest {
-
- @Mock
- private DaoA daoA;
-
- @Mock
- private ServiceC serviceC;
-
- @InjectMocks
- private ServiceA serviceA;
-
-
- @Test
- public void testGetItem() throws Exception {
-
- Mockito.when(daoA.getItem(any(AAA.class))).thenAnswer(invocationOnMock -> {
- return xxx;
- });
-
- assertTrue(serviceA.getItem() != null);
-
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。