使用spring boot , MockBean

1 @RunWith(SpringRunner.class)
2 @SpringBootTest(classes = Application.class)
3 public class DalListTest {
4 
5     @MockBean
6     private  XxxService xxxService;
7 
8 }

classes指定主程序的入口

@MockBean可以在代替实际的Bean, 用来解决一些初始化问题, 比如用例启动不了。不需要在测试类中使用@Configuration, @Bean

默认查找bean的package和主程序入口package相同

mock maven依赖

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>${mockito.version}</version>
</dependency>

  

@SpringBootTest是用在集成测试阶段的,单元测试中不要用这个,  而且单元测试的代码需要和集成测试的代码分开
TDD实践中是先做单元测试,然后实现代码, 再做集成测试

单元测试 是先建立验证目标, 然后实现具体代码。
单元测试时 只需要@RunWith(SpringRunner.class),不要@SpringBootTest
比如只验证controller时, service层的bean是mock打桩, 配合@WebMvcTest就够了
只验证service时, 使用@RunasJunit就行, mock mapper bean
只验证orm时, 使用@JdbcTest,要导入MybatisAutoConfig, 默认不会自动加载autoConfig类。
此时也是要初始化DataSource, sqlSessionFactory ..., 只不过@JdbcTest帮我们初始化了,不用再手动new相关对象
@JdbcTest会自动使用h2数据库, 如果想使用xml中的jdbc路径,需要修改配置spring.test.database.replace=none, springboot1,2版本稍有区别
 1 @ActiveProfiles("test,local")
 2 @RunWith(SpringRunner.class)
 3 @ImportAutoConfiguration(classes = {MybatisPlusAutoConfiguration.class, JdbcTemplateAutoConfiguration.class})
 4 @JdbcTest
 5 @WebAppConfiguration
 6 public class ApiAddressDaoTest {
 7 
 8     @Autowired
 9     private ApiAddressDao apiAddressDao;
10 
11     @Autowired
12     private JdbcTemplate jdbcTemplate;
13 
14     @Test
15     public void test_queryList() {
16 
17         // 打桩  如果使用entityManager 会自动创建表
18         jdbcTemplate.execute("create table ns_address (id int null, user_id int)");
19         jdbcTemplate.execute("insert into ns_address values(11, 156)");
20         
21         // 验证
22         List<AddressVo> addressVos = apiAddressDao.listAddress(156L);
23         assertThat(addressVos).isNotEmpty();
24     }
25 
26 }

 

https://www.baeldung.com/spring-boot-testing
https://github.com/mbhave/tdd-with-spring-boot

@TestPropertySource(xxx.properties) 会覆盖application.properties中的配置

spring boot test MockBean

 

 

@DataJpaTest(excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Service.class))
相当于ComponentScan中的excludeFilters,  用于排除一些不想初始化的bean, 可基于annotation、 ASPECTJ、REGEX等过滤
excludeAutoConfiguration属性可以排除一些AutoConfiguration类(有些autoconfig初始化很麻烦,unit test又用不到)

与集成测试的区别是生成的ApplicationContext类型不同,自动扫描的bean不同, 但都会生成BeanFactory,
作为应用跑起来时是WebApplicationContext, 作为测试类跑起来时TestA

如果应用主类包含ComponentScan, 会影响bean的加载,@DataJpaTest可能会加载service bean, 此时需要ConditionalOnXXXX排除主类的ComponentScan


MockitoAnnotations.initMocks(this)

spy()的作用

Mockito "spy" function, 
which wraps a real object with a mock object. 
All calls to the mock object get forwarded to the real object, except those you are trying to mock. 

然后才能用when(mockBean).doXXX()方法

新版本的mockito可以直接mockStatic(xxx.class)

final static field是可以使用反射修改的

修改 'modifiers'里的final标识位, 直接把final remove掉


static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(null, newValue);
    }




 单元测试的优点和价值:

1.  基准测试, 有对比, 可验证,建立修改的信心

2.  文档作用   

3.  可重用  速度快 不用每次都找前端要参数

 

 

 

相关文章:

  • 2021-10-13
  • 2021-12-28
  • 2021-12-06
  • 2022-03-05
  • 2021-08-18
  • 2021-10-28
  • 2022-12-23
猜你喜欢
  • 2021-05-20
  • 2022-02-22
  • 2022-12-23
  • 2021-08-17
  • 2021-12-23
  • 2021-09-05
  • 2022-12-23
相关资源
相似解决方案