前兩篇文章的主要內(nèi)容是:為了給執(zhí)行測(cè)試,如何建立數(shù)據(jù)庫(kù)表和導(dǎo)入初始數(shù)據(jù)。這里我們將學(xué)習(xí)如何利用Mockito框架和一些注解模擬(mock)Repository實(shí)例,從而使得測(cè)試用例不依賴外部的數(shù)據(jù)庫(kù)服務(wù)。
我們需要?jiǎng)?chuàng)建一個(gè)Spring Boot配置類,在該類中定義用于測(cè)試的Spring Bean;我們通過(guò)注解指示Spring Boot何時(shí)加載測(cè)試配置類以及何時(shí)執(zhí)行該類中的代碼。在改配置類中,我們將使用Mockito框架創(chuàng)建一些帶預(yù)定義方法的mock對(duì)象,Spring Boot在執(zhí)行測(cè)試用例之前會(huì)將這些對(duì)象織入。
@Configuration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = @ComponentScan.Filter(UsedForTesting.class))
@EnableScheduling
public class BookPubApplication {
public static void main(String[] args) {
SpringApplication.run(BookPubApplication.class, args);
}
@Bean
public StartupRunner schedulerRunner() {
return new StartupRunner();
}
}
@interface UsedForTesting {}
src/test/java/com/test/bookpub
目錄下創(chuàng)建TestMockBeansConfig文件,內(nèi)容是:package com.test.bookpub;
import com.test.bookpub.repository.PublisherRepository;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
@UsedForTesting
public class TestMockBeansConfig {
@Bean
@Primary
public PublisherRepository createMockPublisherRepository() {
return Mockito.mock(PublisherRepository.class);
}
}
package com.test.bookpub;
import com.test.bookpub.repository.PublisherRepository;
import org.junit.After;import org.junit.Before;import org.junit.Test;
import org.junit.runner.RunWith;import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {
BookPubApplication.class,
TestMockBeansConfig.class
})
@IntegrationTest
public class PublisherRepositoryTests {
@Autowired
private PublisherRepository repository;
@Before
public void setupPublisherRepositoryMock() {
Mockito.when(repository.count())
.thenReturn(1L);
}
@Test
public void publishersExist() {
assertEquals(1, repository.count());
}
@After
public void resetPublisherRepositoryMock() {
Mockito.reset(repository);
}
}
OK,分析下剛剛發(fā)生了什么。首先,我們從對(duì)BookPubApplication.java的修改開始:
接下來(lái)看看在TestMockBeansConfig中的操作,
最后看下我們的測(cè)試用例,主要關(guān)注setupPublisherRepositoryMock方法和resetPublisherRepositoryMock方法:
setupPublisherRepositoryMock方法被@Before注解修飾,表示在測(cè)試用例運(yùn)行之前被調(diào)用,在這個(gè)方法中我們配置了mock對(duì)象的行為:如果收到repository.count()調(diào)用,則返回1。Mockito框架提供了很多DSL形式的語(yǔ)句,可以用于定義這些容易理解的規(guī)則。