最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java使用Mockito進(jìn)行模擬和測(cè)試樁實(shí)踐過(guò)程

 更新時(shí)間:2026年04月24日 14:34:38   作者:Java技術(shù)攻略  
本文介紹了Mockito框架的基本概念、使用方法和進(jìn)階用法,包括模擬對(duì)象、測(cè)試樁、參數(shù)匹配、異步測(cè)試、void方法的樁方法和驗(yàn)證、mock靜態(tài)方法和final方法等內(nèi)容,Mockito是一個(gè)流行的Java模擬框架,具有簡(jiǎn)單易用、支持廣泛、文檔豐富的優(yōu)點(diǎn)

Mockito是一個(gè)流行的Java模擬框架,用于編寫(xiě)單元測(cè)試代碼時(shí)模擬(mock)和測(cè)試樁(stub)對(duì)象的行為??奢p松模擬Java類和接口的行為,幫助測(cè)試人員和開(kāi)發(fā)人員更好地設(shè)計(jì)和執(zhí)行單元測(cè)試。

使用Mockito,開(kāi)發(fā)人員可以模擬一個(gè)對(duì)象,使其表現(xiàn)出某些預(yù)期的行為,而無(wú)需使用真實(shí)對(duì)象。

這種技術(shù)通常用于在不使用復(fù)雜的集成測(cè)試環(huán)境的情況下測(cè)試代碼。Mockito可以協(xié)助進(jìn)行單元測(cè)試、集成測(cè)試和行為驅(qū)動(dòng)開(kāi)發(fā)(BDD)。

一、Mockito基礎(chǔ)知識(shí)

1、Mockito的優(yōu)點(diǎn)

  • 使用簡(jiǎn)單:Mockito的API簡(jiǎn)單明了,易于學(xué)習(xí)和使用。
  • 支持多種場(chǎng)景:Mockito支持各種測(cè)試場(chǎng)景,如單元測(cè)試、集成測(cè)試和BDD等。
  • 良好的文檔:Mockito擁有全面的文檔和用戶群體,可以提供許多使用方案和實(shí)例。

2、Mockito的局限性

  • 不支持靜態(tài)方法和final方法的模擬。
  • 可能會(huì)過(guò)度使用,導(dǎo)致測(cè)試代碼的維護(hù)難度增加。

3、Mockito的常見(jiàn)概念

  • Mock:指一個(gè)對(duì)象的虛擬實(shí)現(xiàn),具有與真實(shí)對(duì)象相同的方法和屬性,但不會(huì)真正執(zhí)行其中的方法。
  • Stub:指為某個(gè)方法調(diào)用提供預(yù)定義返回值的代碼,通常用于控制測(cè)試中的代碼路徑。
  • Verify:指驗(yàn)證Mock對(duì)象是否按照預(yù)期進(jìn)行了交互。Verify可用于驗(yàn)證Mock對(duì)象的方法是否被調(diào)用了特定的次數(shù),并且傳入了預(yù)期的參數(shù)。

4、Mockito的常見(jiàn)用法

  • 創(chuàng)建Mock對(duì)象
List mockList = mock(List.class);
  • Stub方法調(diào)用
when(mockList.get(0)).thenReturn("first");
  • 驗(yàn)證方法調(diào)用
verify(mockList).add("one");
  • 模擬方法拋出異常
when(mockList.get(anyInt())).thenThrow(new RuntimeException());
  • 模擬連續(xù)調(diào)用

Mockito提供了許多其他功能,如ArgumentMatchers用于匹配方法調(diào)用的參數(shù)、Annotations用于對(duì)Mock對(duì)象進(jìn)行注釋、Spy用于監(jiān)視真實(shí)對(duì)象等等。

通過(guò)學(xué)習(xí)和掌握Mockito的使用,可以更加高效地進(jìn)行單元測(cè)試和集成測(cè)試。

二、使用Mockito進(jìn)行模擬

1、使用Mockito進(jìn)行模擬的步驟和示例

Mockito可以通過(guò)模擬對(duì)象來(lái)測(cè)試代碼,步驟如下:

導(dǎo)入Mockito庫(kù)。在pom.xml文件中添加以下依賴:

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>

創(chuàng)建要測(cè)試的類和方法

public class UserService {
private UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public User getUserById(int id) {
return userDao.getUserById(id);
}
}
public interface UserDao {
User getUserById(int id);
}

創(chuàng)建一個(gè)模擬對(duì)象

UserDao userDao = mock(UserDao.class);

設(shè)置模擬對(duì)象的行為

when(userDao.getUserById(1)).thenReturn(new User(1, "John"));

運(yùn)行測(cè)試代碼

@Test
public void testGetUserById() {
UserDao userDao = mock(UserDao.class);
when(userDao.getUserById(1)).thenReturn(new User(1, "John"));
UserService userService = new UserService(userDao);
User user = userService.getUserById(1);
assertEquals(user.getId(), 1);
assertEquals(user.getName(), "John");
}

2、使用when()

Mockito的when()方法可以用于設(shè)置模擬對(duì)象的行為,例如:

when(mockObject.someMethod()).thenReturn(someValue);

示例代碼:

@Test
public void testGetUserById() {
UserDao userDao = mock(UserDao.class);
when(userDao.getUserById(1)).thenReturn(new User(1, "John"));
UserService userService = new UserService(userDao);
User user = userService.getUserById(1);
assertEquals(user.getId(), 1);
assertEquals(user.getName(), "John");
}

3、使用doReturn()

doReturn()方法與when()方法類似,可以用于設(shè)置模擬對(duì)象的行為,例如:

doReturn(someValue).when(mockObject).someMethod();

示例代碼:

@Test
public void testGetUserById() {
UserDao userDao = mock(UserDao.class);
doReturn(new User(1, "John")).when(userDao).getUserById(1);
UserService userService = new UserService(userDao);
User user = userService.getUserById(1);
assertEquals(user.getId(), 1);
assertEquals(user.getName(), "John");
}

4、使用mock()方法創(chuàng)建模擬對(duì)象

mock()方法可以用于創(chuàng)建模擬對(duì)象,例如:

SomeClass mockObject = mock(SomeClass.class);

示例代碼:

@Test
public void testGetUserById() {
UserDao userDao = mock(UserDao.class);
when(userDao.getUserById(1)).thenReturn(new User(1, "John"));
UserService userService = new UserService(userDao);
User user = userService.getUserById(1);
assertEquals(user.getId(), 1);
assertEquals(user.getName(), "John");
}

5、使用@Mock注解創(chuàng)建模擬對(duì)象

除了使用 ?mock()??? 方法創(chuàng)建模擬對(duì)象外,還可以使用 ??@Mock?? 注解來(lái)創(chuàng)建模擬對(duì)象。

首先需要在測(cè)試類中使用 ??@RunWith(MockitoJUnitRunner.class)?? 注解,以便在運(yùn)行測(cè)試時(shí)自動(dòng)初始化模擬對(duì)象。

接著在測(cè)試類中使用 ??@Mock?? 注解創(chuàng)建模擬對(duì)象,如下所示:

@Mock
private UserDao userDao;
@Test
public void testGetUserById() {
UserService userService = new UserService(userDao);

使用 ??@Mock?? 注解創(chuàng)建模擬對(duì)象時(shí),需要注意以下幾點(diǎn):

  • 被 ??@Mock??? 注解修飾的變量不能為 ??null??。
  • 被 ??@Mock??? 注解修飾的變量默認(rèn)為 ??@Mock(answer = RETURNS_DEFAULTS)??。
  • 可以通過(guò) ??@Mock(answer =Answers.RETURNS_SMART_NULLS)??? 顯式指定返回智能 ??null??。
  • 使用 ??@Mock?? 注解創(chuàng)建模擬對(duì)象時(shí),Mockito 會(huì)自動(dòng)創(chuàng)建并初始化模擬對(duì)象,并將其注入測(cè)試類中。

注意,使用 ??@Mock??? 注解創(chuàng)建的模擬對(duì)象需要在測(cè)試類中使用,否則會(huì)拋出 ??UnnecessaryStubbingException?? 異常。

6、使用@Spy注解進(jìn)行模擬對(duì)象的部分模擬

除了使用@Mock注解創(chuàng)建一個(gè)完整的模擬對(duì)象之外,Mockito還提供了@Spy注解來(lái)創(chuàng)建部分模擬對(duì)象,這樣可以在保留真實(shí)對(duì)象部分行為的同時(shí),對(duì)其它行為進(jìn)行模擬。

下面是@Spy注解的使用示例:

public class ExampleServiceTest {
@Spy
private ExampleServiceImpl exampleServiceSpy;
@Test
public void testSomeMethod() {
// 對(duì)exampleServiceSpy進(jìn)行部分模擬,保留真實(shí)對(duì)象的部分行為
Mockito.doCallRealMethod().when(exampleServiceSpy).someMethod();
// 對(duì)someOtherMethod進(jìn)行模擬
Mockito.when(exampleServiceSpy.someOtherMethod()).thenReturn("mocked result");
// 執(zhí)行測(cè)試代碼,調(diào)用exampleServiceSpy.someMethod()方法
exampleServiceSpy.someMethod();
// 驗(yàn)證someMethod()方法中是否調(diào)用了someOtherMethod()方法
Mockito.verify(exampleServiceSpy).someOtherMethod();
}
}

在這個(gè)例子中,我們使用了@Spy注解來(lái)創(chuàng)建一個(gè)ExampleServiceImpl對(duì)象的部分模擬。然后,我們使用了??Mockito.doCallRealMethod().when(exampleServiceSpy).someMethod();??來(lái)保留exampleServiceSpy對(duì)象中someMethod()方法的真實(shí)行為,而對(duì)someOtherMethod()方法進(jìn)行了模擬。

最后,我們調(diào)用了exampleServiceSpy.someMethod()方法,并驗(yàn)證了someOtherMethod()方法是否被調(diào)用。

三、使用Mockito進(jìn)行測(cè)試樁

1、測(cè)試樁的作用和場(chǎng)景

使用Mockito進(jìn)行測(cè)試樁可以在單元測(cè)試中模擬方法的返回值或拋出異常,以便測(cè)試被測(cè)代碼在各種情況下的行為。

常見(jiàn)的使用場(chǎng)景包括:

  • 測(cè)試被測(cè)代碼在異常情況下的行為。通過(guò)測(cè)試樁可以模擬方法拋出異常的場(chǎng)景,測(cè)試被測(cè)代碼在異常情況下是否能夠正確地處理異常。
  • 測(cè)試被測(cè)代碼在特定情況下的行為。例如,測(cè)試一個(gè)方法在輸入為null時(shí)的行為,可以使用測(cè)試樁模擬方法的輸入為null的場(chǎng)景。
  • 測(cè)試被測(cè)代碼與外部依賴的交互。通過(guò)模擬外部依賴的返回值或拋出異常,可以測(cè)試被測(cè)代碼在與外部依賴交互時(shí)的行為。
  • 測(cè)試被測(cè)代碼的邊界條件。通過(guò)模擬外部依賴或方法的返回值,可以測(cè)試被測(cè)代碼在各種邊界情況下的行為,例如輸入為最大值或最小值的情況。
  • 總之,測(cè)試樁可以幫助開(kāi)發(fā)人員創(chuàng)建各種測(cè)試場(chǎng)景,以確保被測(cè)代碼的行為正確。

2、使用Mockito進(jìn)行測(cè)試樁的步驟和示例

使用Mockito進(jìn)行測(cè)試樁可以模擬需要的返回值或異常,以便在測(cè)試中測(cè)試需要的場(chǎng)景。

以下是使用Mockito進(jìn)行測(cè)試樁的步驟和示例:

創(chuàng)建需要進(jìn)行測(cè)試樁的對(duì)象或接口:

public interface UserService {
User getUserById(int userId);
}

使用Mockito進(jìn)行測(cè)試樁,例如模擬getUserById方法返回指定的User對(duì)象:

@Test
public void testGetUserById() {
UserService userService = Mockito.mock(UserService.class);
User expectedUser = new User("Alice", 20);
Mockito.when(userService.getUserById(Mockito.anyInt())).thenReturn(expectedUser);
User actualUser = userService.getUserById(1);
Assert.assertEquals(expectedUser, actualUser);
}

在這個(gè)示例中,我們使用Mockito.mock()方法創(chuàng)建了一個(gè)UserService對(duì)象的模擬對(duì)象userService,并使用Mockito.when()方法對(duì)getUserById方法進(jìn)行測(cè)試樁,指定了當(dāng)傳入任何整數(shù)時(shí)返回一個(gè)指定的User對(duì)象。然后我們使用模擬對(duì)象userService調(diào)用getUserById方法,并斷言返回的User對(duì)象是否是我們期望的值。

使用測(cè)試樁模擬拋出異常:

@Test(expected = UserNotFoundException.class)
public void testGetUserByIdWhenUserNotFound() {
UserService userService = Mockito.mock(UserService.class);
Mockito.when(userService.getUserById(Mockito.anyInt())).thenThrow(UserNotFoundException.class);
userService.getUserById(1);
}

在這個(gè)示例中,我們使用Mockito.when()方法對(duì)getUserById方法進(jìn)行測(cè)試樁,指定了當(dāng)傳入任何整數(shù)時(shí)拋出一個(gè)UserNotFoundException異常。然后我們使用模擬對(duì)象userService調(diào)用getUserById方法,并期望捕獲UserNotFoundException異常。

3、使用thenReturn()方法設(shè)置樁值

除了使用doReturn()方法進(jìn)行樁方法之外,我們還可以使用thenReturn()方法來(lái)設(shè)置樁值。當(dāng)樁方法返回一個(gè)值時(shí),我們可以使用thenReturn()方法來(lái)指定這個(gè)值。

例如:

@Test
public void testGetPerson() {
// 創(chuàng)建模擬對(duì)象
PersonDao personDao = mock(PersonDao.class);
// 設(shè)置樁方法并返回模擬數(shù)據(jù)
when(personDao.getPerson(1)).thenReturn(new Person("Alice", 20));
// 執(zhí)行被測(cè)試方法
PersonService personService = new PersonService(personDao);
Person person = personService.getPerson(1);
// 驗(yàn)證方法的返回值是否正確
assertEquals("Alice", person.getName());
assertEquals(20, person.getAge());
}

在這個(gè)例子中,我們通過(guò)when()方法設(shè)置樁方法,并使用thenReturn()方法指定了當(dāng)getPerson()方法傳入?yún)?shù)1時(shí)應(yīng)該返回的模擬數(shù)據(jù)。然后,我們執(zhí)行被測(cè)試的方法,并使用assertEquals()方法驗(yàn)證方法的返回值是否正確。如果方法返回了我們預(yù)期的模擬數(shù)據(jù),那么測(cè)試就通過(guò)了。

4、使用thenThrow()方法拋出異常

Mockito 的 thenThrow() 方法可以用來(lái)設(shè)置測(cè)試樁方法在執(zhí)行時(shí)拋出指定異常。這對(duì)于測(cè)試某些異常情況下的代碼行為非常有用。

使用 thenThrow() 方法非常簡(jiǎn)單,只需要在樁方法后調(diào)用 thenThrow() 方法,并傳入要拋出的異常類型即可。

以下是一個(gè)示例:

@Test
public void testDoSomething() throws Exception {
SomeObject mockObject = mock(SomeObject.class);
when(mockObject.doSomething()).thenThrow(new RuntimeException("test exception"));
// 確保調(diào)用 doSomething() 時(shí)會(huì)拋出 RuntimeException
assertThrows(RuntimeException.class, () -> {
mockObject.doSomething();
});
}

在上面的示例中,我們使用 ??when()??? 方法對(duì) ??doSomething()??? 方法進(jìn)行樁,然后調(diào)用 ??thenThrow()??? 方法并傳入一個(gè) ??RuntimeException??? 對(duì)象。然后我們調(diào)用 ??doSomething()??? 方法,這時(shí)候會(huì)拋出一個(gè)運(yùn)行時(shí)異常。最后,我們使用 JUnit 的 ??assertThrows()?? 方法來(lái)驗(yàn)證方法確實(shí)拋出了運(yùn)行時(shí)異常。

總的來(lái)說(shuō),使用 ??thenThrow()?? 方法可以幫助我們測(cè)試代碼在異常情況下的行為。

5、使用doAnswer()方法自定義樁方法

在某些情況下,可能需要自定義樁方法來(lái)滿足測(cè)試的需要。這時(shí)可以使用Mockito的doAnswer()方法來(lái)實(shí)現(xiàn)。

doAnswer()方法如下:

public <T> OngoingStubbing<T> doAnswer(Answer<?> answer)

doAnswer()方法的參數(shù)是一個(gè)Answer對(duì)象,該對(duì)象表示自定義的樁方法的行為。Answer接口中有一個(gè)方法??answer()??,該方法返回一個(gè)泛型對(duì)象,表示模擬方法的返回值。

下面是一個(gè)使用doAnswer()方法自定義樁方法的示例:

List<String> list = mock(List.class);
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
String result = (String) args[0] + "Mockito";
return result;
}).when(list).get(anyInt());

這個(gè)例子中,我們自定義了List的get方法,將其返回值修改為輸入?yún)?shù)的字符串后面加上"Mockito"??梢钥吹?,在doAnswer()方法中,我們實(shí)現(xiàn)了Answer接口的??answer()??方法,并使用Invocation對(duì)象來(lái)獲取傳入的參數(shù)和返回值。最后使用when()方法來(lái)應(yīng)用樁方法。

6、使用@Captor注解進(jìn)行參數(shù)捕獲

Mockito提供了@Captor注解來(lái)捕獲模擬對(duì)象方法調(diào)用中傳入的參數(shù)。這個(gè)注解可以在測(cè)試用例中聲明一個(gè)參數(shù),并將其注解為@Captor,Mockito會(huì)自動(dòng)將模擬對(duì)象方法調(diào)用中的參數(shù)注入到這個(gè)參數(shù)中,以便我們進(jìn)行斷言或其他操作。

使用@Captor注解進(jìn)行參數(shù)捕獲的步驟和示例如下:

在測(cè)試用例類中創(chuàng)建@Captor注解,并初始化一個(gè)參數(shù),例如:

@Captor
private ArgumentCaptor<String> captor;

在測(cè)試用例中使用模擬對(duì)象調(diào)用方法,并將參數(shù)傳遞給模擬對(duì)象,例如:

mockObject.doSomething("test");

使用Mockito.verify()方法驗(yàn)證模擬對(duì)象方法的調(diào)用,并使用@Captor注解捕獲方法調(diào)用時(shí)傳遞的參數(shù),例如:

verify(mockObject).doSomething(captor.capture());

對(duì)捕獲的參數(shù)進(jìn)行斷言或其他操作,例如:

assertEquals("test", captor.getValue());

這樣,就可以使用@Captor注解進(jìn)行參數(shù)捕獲,方便我們?cè)跍y(cè)試用例中對(duì)方法參數(shù)進(jìn)行斷言和其他操作。

四、Mockito進(jìn)階用法

1、使用Mockito進(jìn)行異步測(cè)試

在異步編程中,我們經(jīng)常需要對(duì)異步方法進(jìn)行測(cè)試,確保它們能夠按照預(yù)期工作。Mockito提供了一些方法來(lái)處理異步測(cè)試場(chǎng)景,包括異步回調(diào)和等待異步結(jié)果。

下面是使用Mockito進(jìn)行異步測(cè)試的一些常見(jiàn)場(chǎng)景和示例。

模擬異步回調(diào)

在異步回調(diào)中,當(dāng)一個(gè)異步操作完成時(shí),它將調(diào)用一個(gè)回調(diào)函數(shù)來(lái)通知調(diào)用方。Mockito提供了??Answer??接口,可以使用它來(lái)模擬異步回調(diào)函數(shù)。

示例:

@Test
public void testAsyncCallback() {
MyAsyncService service = mock(MyAsyncService.class);
when(service.doSomethingAsync(anyString(), any(Consumer.class))).thenAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String arg1 = (String) args[0];
Consumer<String> callback = (Consumer<String>) args[1];
callback.accept(arg1 + " is done");
return null;
}
});
MyAsyncClient client = new MyAsyncClient(service);
String result = client.doSomething("test");
assertEquals("test is done", result);
}

在這個(gè)示例中,我們使用??Answer???接口來(lái)模擬異步回調(diào)函數(shù)。當(dāng)??service.doSomethingAsync???方法被調(diào)用時(shí),我們從參數(shù)中獲取回調(diào)函數(shù)并執(zhí)行它,然后返回??null??。在測(cè)試中,我們驗(yàn)證異步客戶端返回的結(jié)果是否正確。

等待異步結(jié)果

在異步編程中,我們經(jīng)常需要等待異步操作完成后獲取結(jié)果。為了測(cè)試異步方法,我們需要等待異步操作完成后再斷言結(jié)果。Mockito提供了一些方法來(lái)處理這種場(chǎng)景。

示例:

@Test
public void testAsyncResult() throws Exception {
MyAsyncService service = mock(MyAsyncService.class);
CompletableFuture<String> future = new CompletableFuture<>();
when(service.doSomethingAsync(anyString())).thenReturn(future);
MyAsyncClient client = new MyAsyncClient(service);
CompletableFuture<String> result = client.doSomethingAsync("test");
assertFalse(result.isDone()); // 驗(yàn)證異步方法還未完成
future.complete("test is done");
assertTrue(result.isDone()); // 驗(yàn)證異步方法已完成
assertEquals("test is done", result.get()); // 驗(yàn)證異步方法的結(jié)果是否正確
}

在這個(gè)示例中,我們使用??CompletableFuture???來(lái)模擬異步方法的結(jié)果。當(dāng)??service.doSomethingAsync???方法被調(diào)用時(shí),我們返回一個(gè)??CompletableFuture???對(duì)象。在測(cè)試中,我們驗(yàn)證異步方法是否已經(jīng)啟動(dòng),然后手動(dòng)完成??CompletableFuture??對(duì)象并驗(yàn)證結(jié)果是否正確。

需要注意的是,在使用??CompletableFuture???對(duì)象進(jìn)行異步測(cè)試時(shí),我們需要等待異步操作完成后再獲取結(jié)果。

我們可以使用??isDone()???方法來(lái)判斷異步操作是否完成,使用??get()??方法來(lái)獲取異步操作的結(jié)果。

2、使用Mockito進(jìn)行參數(shù)匹配

在使用 Mockito 進(jìn)行單元測(cè)試時(shí),我們通常需要對(duì)被測(cè)方法傳入不同的參數(shù)進(jìn)行測(cè)試。但有時(shí)候我們希望只測(cè)試特定的參數(shù)組合,這時(shí)候就需要使用參數(shù)匹配。

Mockito 提供了一系列的參數(shù)匹配器,可以根據(jù)參數(shù)類型和值來(lái)匹配參數(shù)。

常用的參數(shù)匹配器有:

  • any():匹配任何對(duì)象,例如 any(String.class) 匹配任何 String 類型的參數(shù)。
  • eq():匹配指定的對(duì)象,例如 eq("abc") 匹配參數(shù)值為 "abc" 的參數(shù)。
  • isA():匹配指定類型的參數(shù),例如 isA(String.class) 匹配參數(shù)類型為 String 的參數(shù)。
  • anyXxx():匹配指定類型的基本數(shù)據(jù)類型,例如 anyInt() 匹配任何 int 類型的參數(shù)。

下面是使用 Mockito 進(jìn)行參數(shù)匹配的示例代碼:

// 定義被測(cè)類
public class UserService {
private UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public User getUserByName(String name) {
return userDao.getUserByName(name);
}
}
// 定義 UserDao 接口
public interface UserDao {
User getUserByName(String name);
}
// 定義測(cè)試類
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
@Mock
private UserDao userDao;
@InjectMocks
private UserService userService;
@Test
public void testGetUserByName() {
// 設(shè)置樁方法
when(userDao.getUserByName(any(String.class)))
.thenReturn(new User("Tom"));
// 調(diào)用被測(cè)方法
User user = userService.getUserByName("Tom");
// 驗(yàn)證返回值
assertEquals("Tom", user.getName());
}
}

在上面的示例代碼中,我們使用了 any() 方法來(lái)匹配 getUserByName() 方法的參數(shù),這樣就可以匹配任何字符串類型的參數(shù),不需要具體指定參數(shù)值。這樣可以使測(cè)試代碼更加靈活和通用。

除了上面介紹的參數(shù)匹配器外,Mockito 還提供了很多其他的參數(shù)匹配器,具體可以參考 Mockito 的官方文檔。

3、使用Mockito進(jìn)行void方法的樁方法和驗(yàn)證

Mockito可以用于樁方法和驗(yàn)證void方法,下面將介紹如何使用Mockito來(lái)進(jìn)行void方法的樁方法和驗(yàn)證。

void方法的樁方法

Mockito中有兩種方法可以用于void方法的樁方法,分別是doNothing()和doThrow()。

  • doNothing():表示當(dāng)void方法被調(diào)用時(shí),不做任何事情。
  • doThrow():表示當(dāng)void方法被調(diào)用時(shí),拋出一個(gè)指定的異常。

下面是示例代碼:

// 創(chuàng)建一個(gè)mock對(duì)象
List<String> mockList = mock(List.class);
// 對(duì)void方法進(jìn)行樁方法,表示當(dāng)調(diào)用add方法時(shí),不做任何事情
doNothing().when(mockList).add(anyString());
// 對(duì)void方法進(jìn)行樁方法,表示當(dāng)調(diào)用clear方法時(shí),拋出一個(gè)RuntimeException異常
doThrow(new RuntimeException()).when(mockList).clear();

void方法的驗(yàn)證

Mockito中使用verify()方法來(lái)驗(yàn)證void方法是否被調(diào)用,和之前提到的verify()方法類似,只是不需要設(shè)置返回值。

下面是示例代碼:

// 創(chuàng)建一個(gè)mock對(duì)象
List<String> mockList = mock(List.class);
// 調(diào)用void方法
mockList.clear();
// 驗(yàn)證clear方法是否被調(diào)用過(guò)一次
verify(mockList).clear();

使用Mockito進(jìn)行void方法的樁方法和驗(yàn)證和普通方法類似,只需要使用doNothing()、doThrow()方法進(jìn)行樁方法,使用verify()方法進(jìn)行驗(yàn)證即可。

4、使用Mockito進(jìn)行mock靜態(tài)方法和final方法

Mockito 無(wú)法直接 Mock 靜態(tài)方法和 final 方法,因?yàn)樗鼈儾荒鼙蛔宇惢椭剌d,但是 Mockito 可以與 PowerMock 等其他 Mock 框架結(jié)合使用來(lái) Mock 靜態(tài)方法和 final 方法。

PowerMock 是一個(gè) Java 開(kāi)源框架,它結(jié)合了 EasyMock 和 Mockito 的功能,并添加了對(duì)靜態(tài)方法、final 方法、私有方法、構(gòu)造函數(shù)和靜態(tài)初始化塊的支持。

下面是使用 PowerMock 和 Mockito 來(lái) Mock 靜態(tài)方法和 final 方法的步驟和示例:

在 Maven POM 文件中添加 PowerMock 和 Mockito 的依賴項(xiàng):

<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.2.4</version>
<scope>test</scope>
</dependency>

2 使用 @RunWith(PowerMockRunner.class) 和 @PrepareForTest 注解來(lái)準(zhǔn)備需要 Mock 的類:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassToMock.class})
public class MyClassTest {
...
}

3 使用 PowerMockito.mockStatic(ClassToMock.class) 方法來(lái) Mock 靜態(tài)方法:

PowerMockito.mockStatic(ClassToMock.class);
Mockito.when(ClassToMock.staticMethod()).thenReturn(expectedValue);

4 使用 PowerMockito.whenNew(ClassToMock.class) 方法來(lái) Mock 構(gòu)造函數(shù):

PowerMockito.whenNew(ClassToMock.class).withArguments(argument1, argument2).thenReturn(mockInstance);

5 使用 PowerMockito.spy(mockInstance) 方法來(lái)創(chuàng)建一個(gè) Spy 對(duì)象:

ClassToMock mockInstance = PowerMockito.spy(new ClassToMock());
Mockito.when(mockInstance.finalMethod()).thenReturn(expectedValue);

6 使用

PowerMockito.doCallRealMethod().when(mockInstance).nonFinalMethod() 方法來(lái) Mock 非 final 方法:

PowerMockito.doCallRealMethod().when(mockInstance).nonFinalMethod();
Mockito.when(mockInstance.nonFinalMethod()).thenReturn(expectedValue);

7 在測(cè)試方法中,使用 PowerMockito.verifyStatic(ClassToMock.class) 方法來(lái)驗(yàn)證靜態(tài)方法調(diào)用,使用 PowerMockito.verifyNew(ClassToMock.class) 方法來(lái)驗(yàn)證構(gòu)造函數(shù)調(diào)用:

PowerMockito.verifyStatic(ClassToMock.class);
ClassToMock.staticMethod();
PowerMockito.verifyNew(ClassToMock.class).withArguments(argument1, argument2);

需要注意的是,Mock 靜態(tài)方法和 final 方法可能會(huì)影響代碼的可維護(hù)性和可讀性,應(yīng)該盡量避免使用它們。只有在必要時(shí)才使用它們,并且應(yīng)該選擇適當(dāng)?shù)?Mock 框架來(lái)保持代碼的簡(jiǎn)潔性和可讀性。

五、總結(jié)

Mockito是一個(gè)流行的Java模擬框架,它可以幫助開(kāi)發(fā)人員編寫(xiě)單元測(cè)試,以便更好地驗(yàn)證代碼的正確性。

Mockito提供了一些常用的方法,例如模擬對(duì)象、測(cè)試樁、參數(shù)匹配、異步測(cè)試等,這些方法可以大大簡(jiǎn)化測(cè)試代碼的編寫(xiě)和維護(hù)。

Mockito的優(yōu)點(diǎn)包括易學(xué)易用、廣泛支持、文檔豐富等,但也存在局限性,例如不支持mock final方法等。

對(duì)于開(kāi)發(fā)人員而言,使用Mockito進(jìn)行單元測(cè)試可以提高代碼質(zhì)量,降低代碼維護(hù)成本,是一個(gè)非常值得掌握的技能。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java如何給指定類配置單獨(dú)的日志文件輸出

    java如何給指定類配置單獨(dú)的日志文件輸出

    這篇文章主要介紹了java如何給指定類配置單獨(dú)的日志文件輸出問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • 詳解Java中的JDK、JRE、JVM

    詳解Java中的JDK、JRE、JVM

    本文主要介紹了Java中的JDK、JRE、JVM的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • 一篇文章帶你了解Maven的生命周期

    一篇文章帶你了解Maven的生命周期

    這篇文章主要為大家介紹了Maven的生命周期?,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • java實(shí)現(xiàn)簡(jiǎn)單計(jì)算器

    java實(shí)現(xiàn)簡(jiǎn)單計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • IntelliJ IDEA2019實(shí)現(xiàn)Web項(xiàng)目創(chuàng)建示例

    IntelliJ IDEA2019實(shí)現(xiàn)Web項(xiàng)目創(chuàng)建示例

    這篇文章主要介紹了IntelliJ IDEA2019實(shí)現(xiàn)Web項(xiàng)目創(chuàng)建示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Java HtmlParse提取標(biāo)簽中的值操作

    Java HtmlParse提取標(biāo)簽中的值操作

    這篇文章主要介紹了Java HtmlParse提取標(biāo)簽中的值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Spring Boot實(shí)現(xiàn)SSE實(shí)時(shí)推送實(shí)戰(zhàn)示例

    Spring Boot實(shí)現(xiàn)SSE實(shí)時(shí)推送實(shí)戰(zhàn)示例

    本文給大家介紹基于SpringBoot實(shí)現(xiàn)SSE示例,包括創(chuàng)建項(xiàng)目、SSE控制器處理連接與消息推送、跨域配置、客戶端使用EventSource訂閱,以及動(dòng)態(tài)推送和WebFlux擴(kuò)展,感興趣的朋友跟隨小編一起看看吧
    2025-08-08
  • SpringBoot的項(xiàng)目API版本控制方式

    SpringBoot的項(xiàng)目API版本控制方式

    本文主要講述了如何通過(guò)自定義版本控制來(lái)實(shí)現(xiàn)接口版本的管理,主要包括自定義版本號(hào)標(biāo)記注解,重寫(xiě)RequestCondition和RequestMappingHandlerMapping以實(shí)現(xiàn)自定義的URL匹配邏輯,以及配置注冊(cè)自定義的WebMvcRegistrations,最后通過(guò)測(cè)試接口頁(yè)面驗(yàn)證了效果
    2026-05-05
  • 使用SpringBoot整合Jpa的過(guò)程詳解

    使用SpringBoot整合Jpa的過(guò)程詳解

    SpringBoot是一種快速開(kāi)發(fā)框架,它簡(jiǎn)化了Java應(yīng)用程序的開(kāi)發(fā)過(guò)程,而Jpa是Java持久化規(guī)范的一種實(shí)現(xiàn),將SpringBoot與Jpa整合可以更加方便地進(jìn)行數(shù)據(jù)庫(kù)操作,提高開(kāi)發(fā)效率,本文將介紹如何使用Spring Boot整合Jpa,幫助讀者快速上手并應(yīng)用于實(shí)際項(xiàng)目中
    2023-12-12
  • Spring Boot Test詳解

    Spring Boot Test詳解

    Spring Test與JUnit等其他測(cè)試框架結(jié)合起來(lái),提供了便捷高效的測(cè)試手段,而Spring Boot Test 是在Spring Test之上的再次封裝,增加了切片測(cè)試,增強(qiáng)了mock能力,這篇文章主要介紹了Spring Boot Test介紹,需要的朋友可以參考下
    2024-02-02

最新評(píng)論

温泉县| 五大连池市| 绵竹市| 伊金霍洛旗| 衡水市| 班戈县| 正安县| 绥中县| 双桥区| 霍邱县| 玛沁县| 象山县| 合川市| 阳西县| 扶绥县| 遂平县| 康马县| 凤凰县| 邵东县| 清新县| 广丰县| 邮箱| 永善县| 金昌市| 兴宁市| 平潭县| 东港市| 榆林市| 岗巴县| 宝清县| 宣威市| 佛山市| 临夏市| 九江市| 朔州市| 宣恩县| 育儿| 新化县| 梅州市| 神木县| 刚察县|