单元测试在正规项目开发过程中是不可或缺的,像sonar之类的工具可以对项目代码的测试覆盖率都可以统计出来,从测试代码覆盖率上就可以从侧面反应出代码整体运行可能出问题的概率(不是一定),所以大型公司项目对单元测试覆盖率都有明确的要求。
作为现在微服务开发基础的springboot,有必要针对这个框架的单元测试进行必要的探讨,尤其是controller接口的单元测试。springboot针对单元测试提供了很多辅助注解,了解了这些注解就可以轻松的使用这些特性进行微服务的单元测试。
本文仅针对controller接口侧面的单元测试进行阐述,首先看下@WebMvcTest这个注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(WebMvcTestContextBootstrapper.class)
@ExtendWith(SpringExtension.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(WebMvcTypeExcludeFilter.class)
@AutoConfigureCache
@AutoConfigureWebMvc
@AutoConfigureMockMvc
@ImportAutoConfiguration
public @interface WebMvcTest {
/**
* Properties in form {@literal key=value} that should be added to the Spring
* {@link Environment} before the test runs.
* @return the properties to add
* @since 2.1.0
*/
String[] properties() default {};
/**
* Specifies the controllers to test. This is an alias of {@link #controllers()} which
* can be used for brevity if no other attributes are defined. See
* {@link #controllers()} for details.
* @see #controllers()
* @return the controllers to test
*/
@AliasFor("controllers")
Class<?>[] value() default {};
/**
* Specifies the controllers to test. May be left blank if all {@code @Controller}
* beans should be added to the application context.
* @see #value()
* @return the controllers to test
*/
@AliasFor("value")
Class<?>[] controllers() default {};
/**
* Determines if default filtering should be used with
* {@link SpringBootApplication @SpringBootApplication}. By default only
* {@code @Controller} (when no explicit {@link #controllers() controllers} are
* defined), {@code @ControllerAdvice} and {@code WebMvcConfigurer} beans are
* included.
* @see #includeFilters()
* @see #excludeFilters()
* @return if default filters should be used
*/
boolean useDefaultFilters() default true;
/**
* A set of include filters which can be used to add otherwise filtered beans to the
* application context.
* @return include filters to apply
*/
Filter[] includeFilters() default {};
/**
* A set of exclude filters which can be used to filter beans that would otherwise be
* added to the application context.
* @return exclude filters to apply
*/
Filter[] excludeFilters() default {};
/**
* Auto-configuration exclusions that should be applied for this test.
* @return auto-configuration exclusions to apply
*/
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
Class<?>[] excludeAutoConfiguration() default {};
}
1、@WebMvcTest这个注解跟@SpringBootTest这个注解是不兼容的,从上面@WebMvcTest注解的定义来看,@WebMvcTest这个注解支持指定controller的接口测试,这样就可以减少不必要组件的加载时间。
2、@WebMvcTest注解默认扫描 @Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver这些组件,但是不会扫描 @Component, @Service or @Repository等组件,所以如果单独使用@WebMvcTest进行controller接口进行单元测试时,一般还要与@MockBean注解协同使用,下面给出一种用法:
@MockBean
private RemoteService remoteService;
@Autowired
private Reverser reverser;
@Test
void exampleTest() {
// 模拟RemoteService服务someCall接口调用返回值
given(this.remoteService.someCall()).willReturn("mock");
String reverse = reverser.reverseSomeCall();
assertThat(reverse).isEqualTo("kcom");
}
3、如果想使用数据库实际值进行测试,同时测试Service的相关接口流程,也可以使用@SpringBootTest+@AutoConfigureMockMvc注解的配合方式来完成。
总结,本文介绍了两种方式:
1、通过@WebMvcTest与@MockBean(Mock controller里面定义的Service接口)注解
2、通过@SpringBootTest与@AutoConfigureMockMvc注解实现