后台-系统设置-扩展变量-手机广告位-内容正文顶部 |
Junit开发指南
基类
com.enation.app.javashop.framework.test.BaseTest
此类加入了基础的注解:
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest()
@ComponentScan("com.enation.app.javashop")
@Transactional
@Rollback()
publicabstractclassBaseTest{
}
基类加入了事务和自动回滚的注解,那么在单元测试中相应的操作最终会被回滚,而不影响下次测试
bootstrap.yml
需要在src/main/test/resources中定义一个bootstrap.yml,他和main/resources中的只有一项profile不一样:
spring:
application:
name:admin-api
cloud:
config:
uri:http://localhost:8888
label:master
profile:test
server:
port:8082
shardingspheredruid的配置
spring:
shardingsphere:
props:
sql:
show:true
sharding:
default-data-source-name:ds0
datasource:
names:ds0
ds0:
type:com.alibaba.druid.pool.DruidDataSource
driver-class-name:com.mysql.jdbc.Driver
url:jdbc:mysql://192.168.2.115:3306/default_database?useUnicode=true&characterEncoding=utf8&autoReconnect=true
username:root
password:123456
tocken权限
在BaseTest中,定义了seller1,seller2,buyer1,buyer2四个tocken值,不需要在自己的单元测试中重复定义:
示例
@Test
publicvoidtestAdd(){
Mapbrand=newHashMap();
brand.put("name","nametest");
brand.put("logo","logotest");
//执行插入的操作
daoSupport.insert("es_brand",brand);
//在此事务中,插入的数据可见
Stringdblogo=daoSupport.queryForString("selectlogofromes_brandwherename=?","nametest");
//断言中也证明事务可见
Assert.assertEquals(dblogo,"logotest");
//测试结束后,会回滚测试中对数据库的操作
}
多数据源事务
我们系统因分库存在多个数据源,那么默认的事务管理是对商品库的事务管理,如果你的单元测试需要事务回滚,需要在自己的测试类上声明自己的事务管理,比如系统相关的单元测试如果要回滚:
@Transactional(value="systemTransactionManager",rollbackFor=Exception.class)
publicclassSettingManagerTestextendsBaseTest{
...
事务的周期
值得注意的是,每个单元测试(即每个@Test)都是一个事务周期
publicclassMyTestextendsBaseTest{
@Test
publicvoidtestA(){}
@Test
publicvoidtestB(){}
}
如上所示,testA中对数据的操作,在testB中是不可见的,如果有要重复利用的操作,可以在testB中调用testA:
publicclassMyTestextendsBaseTest{
@Test
publicvoidtestA(){}
@Test
publicvoidtestB(){testA();}
}
当然根据你的业务场景需要,可以在自己的单元测试上注解@Rollback(false),来禁用回滚:
@Rollback(false)
publicclassMyTestextendsBaseTest{
...
}
测试数据的准备和清除
如果测试场景需要,可以通过@Before、@After注解来构造、清除测试所需数据:
@Before
publicvoidinsertTestData(){
}
@After
publicvoidcleanTestData(){
}
对象比较断言
为了方便restfulapi的单元测试,在BaseTest中内置了一个对象比较ResultMatcher,使用方法如下:
@Test
publicvoidtestAdd()throwsException{
//构建一个预期的对象
Brandbrand=newBrand();
brand.setName("name1");
brand.setLog("logo1");
//在断言中直接使用objectEquals
mockMvc.perform(post("/goods/brands").param(...)
.andExpect(objectEquals(brand));
}
说明
- objectEquals比较的是controller中的返回值是否和预期的一样
- 实际上是将response的body(json)转为对象,再和预期的对象进行比较
- 这就要求要比较的对象必须实现了equals方法和toString方法
参数的批量校验
在BaseTest中提供了一个构建多参数map的方法toMultiValueMaps,使用示例:
@Test
publicvoidtestAddParams()throwsException{
//定义参数名
String[]names=newString[]{"name","logo","message"};
//定义几组要测试的参数情况和提示信息断言message
String[]values1=newString[]{"","http:www.baidu.com","品牌名称不能为空"};
String[]values2=newString[]{"三只松鼠","","品牌图标不能为空"};
List
for(MultiValueMap
Stringmessage=params.get("message").get(0);
ErrorMessageerror=newErrorMessage("004",message);
mockMvc.perform(post("/goods/brands")
.params(params))
.andExpect(status().is(400))
.andExpect(objectEquals(error));
}
}
当测试参数校验很多的时候,重要的是集中精力排列下面的参数及提示的message:
String[]names=newString[]{"name","logo","message"};
String[]values1=newString[]{"","http:www.baidu.com","品牌名称不能为空"};
String[]values2=newString[]{"三只松鼠","","品牌图标不能为空"};
consumer的测试
consumer的单元测试不用面向消息测试,直接面向业务测试即可,举例说明,假设有如下消费者:
/**
订单状态变化时发送短信
**/
@Component
publicclassOrderSmsMsgSenderimplementsOrderStatusChangeEvent{
@Override
publicvoidorderChange(OrderStatusChangeMsgorderMessage){
//发送短信的代码
}
}
则直接调用此类来测试即可:
publicclassOrderSmsMsgSenderTestextendsBaseTest{
@Autowire
privateOrderSmsMsgSenderorderSmsMsgSender
@Test
publicvoidtestSendSms(){
OrderStatusChangeMsgmsg=newOrderStatusChangeMsg();
msg.setOrdersn("xxxx")
orderSmsMsgSender.orderChange(msg);
//执行断言,略...
}
}
规范
1、测试类的包名,和相应的测试目标的类相同。
2、测试的结果靠断言,而非system.print+肉眼
3、单元测试中不允许出现控制台的输出(system.print)
4、所有controller都必须提供单元测试
5、复杂逻辑的业务类也要提供单元测试
6、在代码请求合并之前,必须保证所有的单元测试通过(包括其他人的)
上述就是关于Junit开发流程的内容了,想了解更多详情,可以持续关注易族智汇javashop,有任何问题,欢迎一起探讨。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。