以下两种方式性能都是一样的,不会去加载spring的启动配置文件
使用的是mock单测工具
package com.example.demo.facade;
import com.example.demo.entity.ProductPriceItemDO;
import com.example.demo.param.ProductIdParam;
import com.example.demo.request.UpdatePriceItemInfoRequest;
import com.example.demo.result.ProductPriceAdjustResult;
import com.example.demo.service.PriceService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author mxl
* @version 1.0
* @created 2021/1/23.
*/
@RunWith(MockitoJUnitRunner.class)
public class ProductPriceAdjustFacadeTest {
@InjectMocks
AdjustFacade facade;
@Mock
PriceService priceService;
@Before
public void setUp() throws Exception {
}
//单元测试(方法层)
@Test
public void getProductPriceAdjustInfo() {
ProductIdParam param = new ProductIdParam();
param.setProductId(100l);
Result result= facade.getProductPriceAdjustInfo(param);
Assert.assertNotNull(result.getAfterProductPriceAdjustInfo());
}
}
如果使用@SpringBootTest注解的话,需要这样配置
package com.example.demo.facade;
import com.example.demo.entity.ProductPriceItemDO;
import com.example.demo.param.ProductIdParam;
import com.example.demo.request.UpdatePriceItemInfoRequest;
import com.example.demo.result.ProductPriceAdjustResult;
import com.example.demo.service.PriceService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.boot.test.context.SpringBootTest;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author mxl
* @version 1.0
* @created 2021/1/23.
*/
@SpringBootTest
public class ProductPriceAdjustFacadeTest {
@InjectMocks
ProductPriceAdjustFacade productPriceAdjustFacade;
@Mock
PriceService priceService;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
//单元测试(方法层)
@Test
public void getProductPriceAdjustInfo() {
ProductIdParam param = new ProductIdParam();
param.setProductId(100l);
ProductPriceAdjustResult productPriceAdjustInfo = productPriceAdjustFacade.getProductPriceAdjustInfo(param);
Assert.assertNotNull(productPriceAdjustInfo.getAfterProductPriceAdjustInfo());
}
}
现在业务开发越来越追求单测覆盖率,对于一些保存方法没有返回值的单测也必须达到覆盖率。
package com.example.demo.facade;
import com.example.demo.entity.ProductPriceItemDO;
import com.example.demo.param.ProductIdParam;
import com.example.demo.request.UpdatePriceItemInfoRequest;
import com.example.demo.result.ProductPriceAdjustResult;
import com.example.demo.service.PriceService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.boot.test.context.SpringBootTest;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author mxl
* @version 1.0
* @created 2021/1/23.
*/
@RunWith(MockitoJUnitRunner.class)
public class ProductPriceAdjustFacadeTest {
@InjectMocks
ProductPriceAdjustFacade productPriceAdjustFacade;
@Mock
PriceService priceService;
@Before
public void setUp() throws Exception {
}
//单元测试(无返回值,参数验证)
@Test
public void batchUpdatePriceItemByCleanPrice(){
productPriceAdjustFacade.batchUpdatePriceItemByCleanPrice();
ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(UpdatePriceItemInfoRequest.class);
verify(priceService).saveBatchProductDatePrice(argumentCaptor.capture());
Assert.assertEquals(new Integer(100), argumentCaptor.getValue().getCleanPrice());
}
}
说明一下
ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(UpdatePriceItemInfoRequest.class);
verify(priceService).saveBatchProductDatePrice(argumentCaptor.capture());
Assert.assertEquals(new Integer(100), argumentCaptor.getValue().getCleanPrice());
这两段代码合起来校验的方法其实是priceService.saveBatchProductDatePrice(UpdatePriceItemInfoRequest updatePriceItemInfo)
很多时候可能单测会涉及到数据库,这时候就需要h2作为单测数据库,使用方式很简单,启动方式使用的是spring的启动类来启动。
测试类:
/**
* @author mxl
* @version 1.0
* @created 2020/12/8.
*/
/**
* UserService测试类
* 单元测试必须开启web环境才能看见h2的控制台
*/
@SpringBootTest(classes = AppBootstrap.class)
@RunWith(SpringRunner.class)
public class GrabBlacklistConsumerTest {
@Autowired
private MblGrabBlacklistMapper mblGrabBlacklistMapper;
@Test
public void insertGrabBlacklist(){
MblGrabBlacklist mblGrabBlacklist = new MblGrabBlacklist();
mblGrabBlacklist.setStatus(1);
mblGrabBlacklist.setProductId(11l);
mblGrabBlacklist.setHostId(33l);
int insert = mblGrabBlacklistMapper.insert(mblGrabBlacklist);
Assert.assertEquals( 1,insert);
}
}
加入h2配置文件
# 是否开启h2数据库注入
h2.test.enabled=true
# 初始化H2数据源的脚本路径。可以不配,默认 test/h2/路径下
h2.test.sqlLocation=
数据库
CREATE TABLE `phx_mbl_grab_blacklist` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`host_id` bigint(20) NOT NULL COMMENT '房东ID',
`product_id` bigint(20) NOT NULL COMMENT '房源ID',
`status` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '黑名单状态,-1:未知,0:已失效,1:生效中',
`expire_date` int(11) unsigned DEFAULT '99991231' COMMENT '到期时间',
`reason` varchar(300) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '拉黑原因',
`blacklist_source` tinyint(2) DEFAULT '-1' COMMENT '拉黑来源,-1:未知,0:系统,1:工单,2:人工',
`gmt_create` datetime NOT NULL COMMENT '创建时间',
`gmt_modify` datetime NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_product_id` (`product_id`),
KEY `idx_host_id` (`host_id`),
KEY `idx_expire_date` (`expire_date`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='抓取黑名单表';
路径情况
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({ "javax.management.*", "javax.net.ssl.*", "javax.security.*" })
//忽略一些mock异常。使用powermock一定要加,否则某些情况下会报错
@PrepareForTest({ BizUtils.class })//要mock的类
public class ProductFacadeTest {
@Before
public void setUp(){
ProductOpInfo opInfo = new ProductOpInfo();
PowerMockito.mockStatic(BizUtils.class);
PowerMockito.when(BizUtils.getCurrentOpInfo()).thenReturn(opInfo);
}
}
@Test
public void queryForTelY_ReturnCalledShowAndCalledNumber(){
// 省略初始化参数
Method privateMethod = planService.getClass().getDeclaredMethod("queryForTelY", CoreBeansCallInInfo.class, CoreBeansPrvNumInfo.class);
privateMethod.setAccessible(true);
CoreBeansCallPlanInfo coreBeansCallPlanInfo = (CoreBeansCallPlanInfo)privateMethod.invoke(planService, callInInfo, prvNumInfo);
assert coreBeansCallPlanInfo.getCallOutShowNum().equals("15320318967");
assert coreBeansCallPlanInfo.getCallTo().equals("密文");
}