mock 測試就是在測試過程中,建立乙個假的物件,避免你為了測試乙個方法,卻要自行構建整個 bean 的依賴鏈。
舉個例子:
類 a 需要呼叫類 b 和類 c,而類 b 和類 c 又需要呼叫其他類如 d、e、f 等,假設類 d 是乙個外部服務,那就會很難測,因為你的返回結果會直接的受外部服務影響,導致你的單元測試可能今天會過、但明天就過不了了。
而當我們引入程式設計客棧 mock 測試時,就可以建立乙個假的物件,替換掉真實的 bean b 和 c,這樣在呼叫b、c的方法時,實際上就會去呼叫這個假的 mock 物件的方法,而我們就可以自己設定這個 mock 物件的引數和期望結果,讓我們可以專注在測試當前的類 a,而不會受到其他的外部服務影響,這樣測試效率就能提高很多。
mockito 是一種 j**a mock 框架,主要就是用來做 mock 測試的,它可以模擬任何 spring 管理的 bean、模擬方法的返回值、模擬丟擲異常等等,同時也會記錄呼叫這些模擬方法的引數、呼叫順序,從而可以校驗出這個 mock 物件是否有被正確的順序呼叫,以及按照期望的引數被呼叫。
像是 mockito 可以在單元測試中模擬乙個 service 返回的資料,而不會真正去呼叫該 service,通過模擬乙個假的 service 物件,來快速的測試當前想要測試的類。
目前在 j**a 中主流的 mock 測試工具有 mockito、jmock、easymock等等,而springboot 目前預設的測試框架是 mockito 框架。
org.springframework.boot
spring-boot-starter-test
www.cppcns.comtest
乙個 userservice,兩個方法
@component
public class userservice
public integer insertuser(user user)
}【pojo物件】
public class user
如果這時候我們先不使用 mockito 模擬乙個假的 userdao bean,而是真的去呼叫乙個正常的 spring bean 的 userdao 的話, 注入 userservice bean,然後去呼叫方法,而他會再去呼叫 userdao 取得資料庫的資料,然後我們再對返回結果做 assert 斷言檢查。
@runwith(springrunner.class)
@springboottest
public class userservicetest
}但是如果 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
}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次。
驗證呼叫順序,驗證 usersewww.cppcns.comrvice 是否先呼叫 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 物件時,有一些限制需要遵守:
因此在寫**時,需要做良好的功能拆分,才能夠使用 mockito 的 mock 技術,幫助我們降低測試時 bean 的耦合度。
軟體測試中Mock和Stub
1.stub 與mock 1 相同點 stub 和mock 物件都是用來模擬外部依賴,使我們能控制。如果被測程式 系統或物件,我們稱之為 a。在測試 a的過程中,a需要與程式 系統或物件 b進行互動,那麼 stub mock 就是用來模擬 b的行為來與 a進行互動。2 不同點 stub 也即 樁 很...
在vue中如何使用mock
1.安裝mockjs npm install mockjs2.在src目錄下建立mock資料夾用來存放生成的資料,在mock資料夾中建立index.js用來作為檔案入口 在index.js中操作 首先引入mock const mock require mockjs import mock from ...
mock方法常用框架 什麼是Mock測試?
私底下接觸到很多童鞋在問關於mock測試的問題,今天就來一篇掃盲文。在單元測試和介面測試過程中通常需要用到mock測試,那麼什麼是mock測試呢?mock 一詞的英文翻譯有模擬 虛擬的意思,所以mock測試可以理解為模擬測試。mock模擬的物件是在測試過程那些不容易構造和獲取的方法 類 物件 介面或...