日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mockito 实战总结笔记

發布時間:2023/12/9 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mockito 实战总结笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

其他 mock 框架:powermock、easymock、jmock

mockito 官網:https://site.mockito.org

mockito 是一個單元測試框架。

Mockito 快速入門

下面來演示 Mockito 的入門案例。

包結構如下:

代碼如下:

實體類 Account.java:

public class Account { }

dao 層 AccountDao.java,該類中有一個接口,并且模擬數據庫宕機的情況:

public class AccountDao {public Account findAccount(String username, String password) {throw new UnsupportedOperationException(); // 模擬數據庫宕機情況}}

controller 層 AccountLoginController.java,該類中有一個接口:

public class AccountLoginController {private final AccountDao accountDao;public AccountLoginController(AccountDao accountDao) {this.accountDao = accountDao;}public String login(HttpServletRequest request) {final String userName = request.getParameter("username");final String password = request.getParameter("password");try {Account account = accountDao.findAccount(userName, password);if (account == null) {return "/login"; // 模擬返回登錄頁面} else {return "/index"; // 模擬登錄成功}} catch (Exception e) {return "/505"; // 模擬出錯情況}}}

此時 controller 層的接口 login() 已經定義好了,現在要對其進行單元測試,但沒有此時這個程序的環境中沒有 servlet 容器,也沒有數據庫,如何進行測試?用 mockito !

AccountLoginControllerTest.java:

import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner;import javax.servlet.http.HttpServletRequest;import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.when;@RunWith(MockitoJUnitRunner.class) // 使用mockito進行單元測試,記得加上這個注解 public class AccountLoginControllerTest {private AccountDao accountDao;private HttpServletRequest request;private AccountLoginController accountLoginController;// 每次測試開始前都會調用該方法,初始化上面定義的變量@Beforepublic void setUp() {this.accountDao = Mockito.mock(AccountDao.class); // 創建一個AccountDao的“替身”this.request = Mockito.mock(HttpServletRequest.class); // 創建一個HttpServletRequest的“替身”this.accountLoginController = new AccountLoginController(accountDao);}// 測試返回"/index"的情況@Testpublic void testLoginSuccess() {Account account = new Account();// 意思是:當調用request.getParameter("username")時,讓request.getParameter("username")返回"john"when(request.getParameter("username")).thenReturn("john"); when(request.getParameter("password")).thenReturn("123456");// anyString():任意字符串when(accountDao.findAccount(anyString(), anyString())).thenReturn(account);// 通過斷言來驗證結果assertThat(accountLoginController.login(request), equalTo("/index"));}// 測試返回"/login"的情況@Testpublic void testLoginFailure() {when(request.getParameter("username")).thenReturn("john");when(request.getParameter("password")).thenReturn("123456");when(accountDao.findAccount(anyString(), anyString())).thenReturn(null);assertThat(accountLoginController.login(request), equalTo("/login"));}// 測試返回"/505"的情況@Testpublic void testLogin505() {when(request.getParameter("username")).thenReturn("john");when(request.getParameter("password")).thenReturn("123456");when(accountDao.findAccount(anyString(), anyString())).thenThrow(UnsupportedOperationException.class); // 注意這調的是thenThrow()assertThat(accountLoginController.login(request), equalTo("/505"));}}

三種不同的 mock 方式

方式一:使用 @RunWith 注解

import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner;import static org.mockito.Mockito.mock;@RunWith(MockitoJUnitRunner.class) public class MockByRunnerTest {@Testpublic void testMock() {AccountDao accountDao = mock(AccountDao.class);Account account = accountDao.findAccount("x", "x");System.out.println(account);}}

打印結果:

null

如果不希望 account 為 null,可以將代碼修改如下:

@Test public void testMock() {AccountDao accountDao = mock(AccountDao.class, Mockito.RETURNS_SMART_NULLS);Account account = accountDao.findAccount("x", "x");System.out.println(account); }

此時打印結果:

SmartNull returned by this unstubbed method call on a mock: accountDao.findAccount("x", "x");

方式二:@Mock 注解

import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations;public class MockByAnnotationTest {@Beforepublic void init() {MockitoAnnotations.initMocks(this);}@Mockprivate AccountDao accountDao;@Testpublic void testMock() {Account account = accountDao.findAccount("x", "x");System.out.println(account);}}

打印結果:

null

同樣,若不想 account 為 null,可按如下編碼:

import org.junit.Before; import org.junit.Test; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations;public class MockByAnnotationTest {@Beforepublic void init() {MockitoAnnotations.initMocks(this);}@Mock(answer = Answers.RETURNS_SMART_NULLS)private AccountDao accountDao;@Testpublic void testMock() {Account account = accountDao.findAccount("x", "x");System.out.println(account);}}

打印結果:

SmartNull returned by this unstubbed method call on a mock: accountDao.findAccount("x", "x");

方式三:@Rule 注解

import org.junit.Rule; import org.junit.Test; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule;import static org.mockito.Mockito.mock;public class MockByRuleTest {@Rulepublic MockitoRule mockitoRule = MockitoJUnit.rule();@Testpublic void testMock() {AccountDao accountDao = mock(AccountDao.class);Account account = accountDao.findAccount("x", "x");System.out.println(account);}}

打印結果:

null

深度 Mock(Deep Mock)

下面的例子中使用 @Mock 注解來進行單元測試:

import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations;import static org.mockito.Mockito.when;public class DeepMockTest {@Mockprivate PersonService personService;@Mockprivate Person person;@Beforepublic void init() {MockitoAnnotations.initMocks(this);}@Testpublic void testDeepMock() {Person person = personService.get();person.foo(); // 此時會報空指針異常}}

此時 testDeepMock() 測試無法通過,會報空指針異常,因為 person 為 null。

為了改進這個問題,將單元測試定義如下:

@Test public void testDeepMock2() {when(personService.get()).thenReturn(person);Person person = personService.get();person.foo(); }

此時可以通過測試,完整代碼如下:

import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations;import static org.mockito.Mockito.when;public class DeepMockTest {@Mockprivate PersonService personService;@Mockprivate Person person;@Beforepublic void init() {MockitoAnnotations.initMocks(this);}@Testpublic void testDeepMock() {Person person = personService.get();person.foo(); // 此時會報空指針異常}@Testpublic void testDeepMock2() {when(personService.get()).thenReturn(person);Person person = personService.get();person.foo();}}

對于上面代碼,可以通過 Deep Mock 方式進行代碼簡化。簡化后的代碼如下:

import org.junit.Before; import org.junit.Test; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations;public class DeepMockTest {@Mock(answer = Answers.RETURNS_DEEP_STUBS) // 指定為Deep Mockprivate PersonService personService;@Beforepublic void init() {MockitoAnnotations.initMocks(this);}@Testpublic void testDeepMock() {personService.get().foo();}}

Mockito Stubbing 語法詳解

#未完待續

參考教程:汪文君Mockito實戰視頻

總結

以上是生活随笔為你收集整理的Mockito 实战总结笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。