JUnit
JUnit 短小精悍,运行单元测试效率高。
@Test
public void testInvalid() {
Set<String> origins = new HashSet<>();
origins.add(UserOriginEnum.LDAP.getDesc());
origins.add("Sorry");
boolean result = UserOriginEnum.isValid(origins);
Assert.assertFalse(result);
}
Mockito
Mockito 短小精悍,运行单元测试效率高,能对不需要执行的方法(Feign接口,短信接口,Redis接口等)进行Mock。
@Mock
ApplicationEventPublisher applicationEventPublisher;
@InjectMocks
@Autowired
IamProjectServiceImpl iamProjectServiceImpl;
@Before
public void before() {
iamProjectServiceImpl.setApplicationEventPublisher(applicationEventPublisher);
Mockito.doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
return "called with arguments: " + args;
}
}).when(applicationEventPublisher).publishEvent(Mockito.any());
}
PowerMockito
PowerMock 功能强大,是Mockito的增强版,支持私有和静态方法的Mock。
CustomUserDetails customUserDetails = new CustomUserDetails("summer","123456");
customUserDetails.setUserId(1L);
PowerMockito.mockStatic(DetailsHelper.class);
PowerMockito.when(DetailsHelper.getUserDetails()).thenReturn(customUserDetails);
SpringTest
SpringTest启动IOC容器和支持DI,能很好的集成JUnit、Mockito和PowerMockito,除了单元测试还支持接口测试。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SteamTechApplication.class})
@Slf4j
public class RuanZhuControllerTest {
@Autowired
WebApplicationContext context;
MockMvc mockMvc;
@Autowired
RuanZhuService ruanZhuService;
@Autowired
AttachmentService attachmentService;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void test_pageRuanZhu_firstPage() throws Exception {
String url = String.format("/v1/site/ruan_zhu/page");
log.info("请求URL:url={}", url);
RuanZhuPageVO vo = RuanZhuPageVO.builder().build();
//vo.setCurrent(2L);
vo.setDesc("id");
String response = mockMvc.perform(post(url).contentType(MediaType.APPLICATION_JSON).content(JSON.toJSONString(vo)))
.andExpect(status().is(200))
.andReturn().getResponse().getContentAsString(); //将相应的数据转换为字符串
String responsePretty = JSON.toJSONString(JSON.parseObject(response), SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteDateUseDateFormat);
log.info("返回报文:responsePretty={}", responsePretty);
}
}
SpringTest 的奇淫技巧
- 启动指定注入类
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@SpringBootTest(classes = {DevSteamIamApplication.class, LiquibaseConfig.class})
@PrepareForTest(UserDetail.class)
@ActiveProfiles("dev")
@Slf4j
- 排除影响容器启动类
exclude排除指定
@SpringBootApplication(
scanBasePackages = {"com.test"},
exclude = {EventAutoConfiguration.class, LiquibaseAutoConfiguration.class}
)
@MapperScan(basePackages = {"com.test.dao"})
@EnableFeignClients({"com.test.fegin", "com.test.api.feign", "com.test.starter"})
@EnableAsync
@EnableTransactionManagement
@Slf4j
public class DevSteamIamApplication {
public static void main(String[] args) {
EurekaEventHandler.getInstance().init();
log.info("已开启EurekaEventHandler");
SpringApplication.run(DevSteamIamApplication.class, args);
}
}
- 全局替换
@TestConfiguration
public class TestStartUpConfig {
@Bean
public EventAutoConfiguration eventAutoConfiguration() {
EventAutoConfiguration eventAutoConfiguration = Mockito.mock(EventAutoConfiguration.class);
return eventAutoConfiguration;
}
@Bean
public SyncIamGrantUserRoleEventListener syncIamGrantUserRoleEventListener() {
SyncIamGrantUserRoleEventListener syncIamGrantUserRoleEventListener = Mockito.mock(SyncIamGrantUserRoleEventListener.class);
return syncIamGrantUserRoleEventListener;
}
}
- @MockBean来解决Feign接口Mock
@MockBean
OauthServiceClient oauthServiceClient;
ResponseEntity<Boolean> body = new ResponseEntity<>(Boolean.TRUE, HttpStatus.OK);
Mockito.when(oauthServiceClient.checkPassword(Mockito.any())).thenReturn(body);
Liquibase 和 H2
SpringBoot application.yml文件配置,SpringTest和 Liquibase、H2能无缝集合,对sit、uat和prod环境数据无任何污染。
有效的支持Devops,非常犀利的组合。
spring:
datasource:
platform: h2
url: jdbc:h2:mem:test
username: sa # 配置数据库用户名
password: sa # 配置数据库密码
driver-class-name: org.h2.Driver # 配置数据库驱动
h2:
console:
path: /h2 # h2 console 访问路径
enabled: true # 开启 console
settings:
web-allow-others: true # 允许远程访问
liquibase:
enabled: true
change-log: classpath:/script/db/changelog-master.xml
Maven集成所有工具
SpringCloud Greenwich.RELEASE, SpringBoot 2.1.6.RELEASE
<!-- ========== Unit Test ========== -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.8.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>test</scope>
</dependency>