使用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中的配置
@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)
單元測試的優點和價值:
1. 基准測試, 有對比, 可驗證,建立修改的信心
2. 文檔作用
3. 可重用 速度快 不用每次都找前端要參數

