您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關怎么在SpringBoot中使用Mockito單元測試,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
Mock 測試就是在測試過程中,創建一個假的對象,避免你為了測試一個方法,卻要自行構建整個 Bean 的依賴鏈。
舉個例子:
類 A 需要調用類 B 和類 C,而類 B 和類 C 又需要調用其他類如 D、E、F 等,假設類 D 是一個外部服務,那就會很難測,因為你的返回結果會直接的受外部服務影響,導致你的單元測試可能今天會過、但明天就過不了了。
而當我們引入 Mock 測試時,就可以創建一個假的對象,替換掉真實的 Bean B 和 C,這樣在調用B、C的方法時,實際上就會去調用這個假的 Mock 對象的方法,而我們就可以自己設定這個 Mock 對象的參數和期望結果,讓我們可以專注在測試當前的類 A,而不會受到其他的外部服務影響,這樣測試效率就能提高很多。
Mockito 是一種 Java Mock 框架,主要就是用來做 Mock 測試的,它可以模擬任何 Spring 管理的 Bean、模擬方法的返回值、模擬拋出異常等等,同時也會記錄調用這些模擬方法的參數、調用順序,從而可以校驗出這個 Mock 對象是否有被正確的順序調用,以及按照期望的參數被調用。
像是 Mockito 可以在單元測試中模擬一個 Service 返回的數據,而不會真正去調用該 Service,通過模擬一個假的 Service 對象,來快速的測試當前想要測試的類。
目前在 Java 中主流的 Mock 測試工具有 Mockito、JMock、EasyMock等等,而 SpringBoot 目前默認的測試框架是 Mockito 框架。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
一個 UserService,兩個方法
getUserById() -------------> 調用 UserDao 這個 bean的 getUserById()
insertUser() -------------> 調用 UserDao 這個 bean的 insertUser()
@Component public class UserService { @Autowired private UserDao userDao; public User getUserById(Integer id) { return userDao.getUserById(id); } public Integer insertUser(User user) { return userDao.insertUser(user); } }
【POJO對象】
public class User { private Integer id; private String name; //省略 getter/setter }
如果這時候我們先不使用 Mockito 模擬一個假的 userDao Bean,而是真的去調用一個正常的 Spring Bean 的 userDao 的話, 注入 userService Bean,然后去調用方法,而他會再去調用 userDao 取得數據庫的數據,然后我們再對返回結果做 Assert 斷言檢查。
@RunWith(SpringRunner.class) @SpringBootTest public class UserServiceTest { //先普通的注入一個userService bean @Autowired private UserService userService; @Test public void getUserById() throws Exception { //普通的使用userService,他里面會再去調用userDao取得數據庫的數據 User user = userService.getUserById(1); //檢查結果 Assert.assertNotNull(user); Assert.assertEquals(user.getId(), new Integer(1)); Assert.assertEquals(user.getName(), "John"); } }
但是如果 userDao 還沒寫好,又想先測 userService 的話,就需要使用 Mockito 去模擬一個假的 userDao 出來。
具體怎么搞呢?
在 userDao 上加上一個 @MockBean 注解
當 userDao 被加上這個注解之后,表示 Mockito 會幫我們創建一個假的 Mock 對象,替換掉 Spring 中已存在的那個真實的 userDao Bean,也就是說,注入進 userService 的 userDao Bean,已經被我們替換成假的 Mock 對象了,所以當我們再次調用 userService 的方法時,會去調用的實際上是 mock userDao Bean 的方法,而不是真實的 userDao Bean。
當我們創建了一個假的 userDao 后,我們需要為這個 mock userDao 自定義方法的返回值,這里有一個公式用法,下面這段代碼的意思為,當調用了某個 Mock 對象的方法時,就回傳我們想要的自定義結果。
Mockito.when( 對象.方法名() ).thenReturn( 自定義結果 )
代碼如下:
@RunWith(SpringRunner.class) @SpringBootTest publicclass UserServiceTest { @Autowired private UserService userService; @MockBean private UserDao userDao; @Test public void getUserById() throws Exception { // 定義當調用mock userDao的getUserById()方法,并且參數為3時,就返回id為200、name為I'm mock3的user對象 Mockito.when(userDao.getUserById(3)).thenReturn(new User(200, "Aritisan")); // 返回的會是名字為I'm mock 3的user對象 User user = userService.getUserById(1); Assert.assertNotNull(user); Assert.assertEquals(user.getId(), new Integer(200)); Assert.assertEquals(user.getName(), "Aritisan"); } }
Mockito 除了最基本的 Mockito.when( 對象.方法名() ).thenReturn( 自定義結果 ),還提供了其他用法讓我們使用。
thenReturn
當使用任何整數值調用 userService 的 getUserById() 方法時,就回傳一個名字為Aritisan的 User 對象。
Mockito.when(userService.getUserById(Mockito.anyInt())).thenReturn(new User(3, "Aritisan")); User user1 = userService.getUserById(3); // 回傳的user的名字為Aritisan User user2 = userService.getUserById(200); // 回傳的user的名字也為Aritisan
限制只有當參數的數字是 3 時,才會回傳名字為 Aritisan 的 user 對象。
Mockito.when(userService.getUserById(3)).thenReturn(new User(3, "Aritisan")); User user1 = userService.getUserById(3); // 回傳的user的名字為Aritisan User user2 = userService.getUserById(200); // 回傳的user為null
當調用 userService 的 insertUser() 方法時,不管傳進來的 user 是什么,都回傳 100。
Mockito.when(userService.insertUser(Mockito.any(User.class))).thenReturn(100); Integer i = userService.insertUser(new User()); //會返回100
thenThrow
當調用 userService 的 getUserById() 時的參數是 9 時,拋出一個 RuntimeException。
Mockito.when(userService.getUserById(9)).thenThrow(new RuntimeException("mock throw exception")); User user = userService.getUserById(9); //會拋出一個RuntimeException
如果方法沒有返回值的話(即是方法定義為 public void myMethod() {…}),要改用 doThrow() 拋出 Exception。
Mockito.doThrow(new RuntimeException("mock throw exception")).when(userService).print(); userService.print(); //會拋出一個RuntimeException
verify
檢查調用 userService 的 getUserById()、且參數為3的次數是否為1次。
驗證調用順序,驗證 userService 是否先調用 getUserById() 兩次,并且第一次的參數是 3、第二次的參數是 5,然后才調用insertUser() 方法。
InOrder inOrder = Mockito.inOrder(userService); inOrder.verify(userService).getUserById(3); inOrder.verify(userService).getUserById(5); inOrder.verify(userService).insertUser(Mockito.any(User.class));
Mockito 注意事項
上述就是 Mockito 的 Mock 對象使用方法,不過當使用 Mockito 在 Mock 對象時,有一些限制需要遵守:
不能 Mock 靜態方法
不能 Mock private 方法
不能 Mock final class
上述就是小編為大家分享的怎么在SpringBoot中使用Mockito單元測試了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。