国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JUnit 5單元測(cè)試(三)—— Mockito 模擬

這篇具有很好參考價(jià)值的文章主要介紹了JUnit 5單元測(cè)試(三)—— Mockito 模擬。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

上一篇講了 JUnit 5單元測(cè)試(二)—— 斷言,書(shū)接上文開(kāi)始 JUnit 5單元測(cè)試(三)—— Mockito 模擬

想象下面這幾種情況你該怎么單元測(cè)試:
1.A方法去數(shù)據(jù)庫(kù)查詢(xún)了數(shù)據(jù)進(jìn)行了一些處理,該怎么單元測(cè)試;
2.在微服務(wù)項(xiàng)目中,A方法中調(diào)用了遠(yuǎn)程微服務(wù)B方法(或者B方法還沒(méi)寫(xiě)好),該怎么單元測(cè)試;
3.A方法中從 redis 或者 Kafka 消息隊(duì)列里取了一些數(shù)據(jù)處理,該怎么單元測(cè)試;

可以看到上面幾種情況如果僅用斷言不能很好的支持單元測(cè)試,這時(shí)候就可以用 Mockito 來(lái)模擬數(shù)據(jù)進(jìn)行單元測(cè)試了。

一、什么是 Mockito

Mockito是一款開(kāi)源測(cè)試庫(kù),簡(jiǎn)稱(chēng) Mock , 該框架允許在自動(dòng)化或單元測(cè)試中模擬對(duì)象。簡(jiǎn)單來(lái)說(shuō)對(duì)于某些不容易構(gòu)造或者不容易獲取的比較復(fù)雜的數(shù)據(jù)/場(chǎng)景,模擬一個(gè)虛假的Mock對(duì)象來(lái)替代真實(shí)的對(duì)象。

想象一下這樣的情景:
一個(gè)用于和支付提供商(如 支付寶、某銀行)通信的 Java類(lèi),如果你測(cè)試時(shí)使用實(shí)時(shí)支付環(huán)境來(lái)對(duì)信用卡收費(fèi)相關(guān)代碼進(jìn)行測(cè)試是很危險(xiǎn)的,而且每次運(yùn)行單元測(cè)試時(shí)都需要實(shí)際連接到支付提供商,這會(huì)使單元測(cè)試具有不確定性,例如,如果支付提供商由于某種原因關(guān)閉了,那就不方便測(cè)試了。

如果你的測(cè)試數(shù)據(jù)依賴(lài)于外部系統(tǒng)、文件讀取時(shí)間過(guò)長(zhǎng)、數(shù)據(jù)庫(kù)連接不可靠,或者你不想在每次測(cè)試時(shí)發(fā)送電子郵件,那么 Mock 很有用。

Mock 一般用于以下情況的單元測(cè)試模擬數(shù)據(jù):

  • 1.MVC接口驗(yàn)證,比如HTTP接口
  • 2.數(shù)據(jù)庫(kù),做單元測(cè)試不需要連接數(shù)據(jù)庫(kù)
  • 3.配置中心、網(wǎng)關(guān)等微服務(wù)發(fā)現(xiàn)治理依賴(lài)
  • 4.Redis、zookeeper、mq消息隊(duì)列等第三方中間件
  • 5.郵件、log、文件等服務(wù)
  • 6.對(duì)其他服務(wù)有依賴(lài)的

二、引入依賴(lài)

		<!-- 由于mockito 5 開(kāi)始支持的最低版本是jdk11,這里使用mockito 4的最新版本來(lái)支持jdk8及以上-->
		<dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>4.11.0</version>
            <scope>test</scope>
        </dependency>
		 <!-- 用于單元測(cè)試中使用@Mock注解時(shí)使用@ExtendWith(MockitoExtension.class)-->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>4.11.0</version>
            <scope>test</scope>
        </dependency>

三、創(chuàng)建 mock 實(shí)例

假設(shè)一個(gè)方法是查詢(xún)數(shù)據(jù)庫(kù)返回List集合,現(xiàn)在通過(guò)mock 來(lái)模擬返回的數(shù)據(jù),首先要?jiǎng)?chuàng)建 mock 實(shí)例來(lái)模擬數(shù)據(jù)。

創(chuàng)建 mock 實(shí)例有三種方法:調(diào)用靜態(tài) mock 方法、調(diào)用openMocks方法+@Mock 注解、Mockito擴(kuò)展+@Mock 注解

后文使用到的 Student 類(lèi)如下:


public class Student {

    public String name;
    public int id;

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String sayHello(String name) {
        return "hello" + name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName(String name,int id) {
        return name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

1. 調(diào)用靜態(tài) mock 方法初始化 mock

在測(cè)試方法里使用 mock 靜態(tài)方法來(lái)模擬一個(gè)對(duì)象實(shí)例:

import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import java.util.List;
import static org.mockito.Mockito.*;

public class MockTest {
    @Test
    public void whenNotUseMockAnnotation_thenCorrect() {
        //使用靜態(tài) mock 方法來(lái)模擬一個(gè) List 對(duì)象
        Student student = mock(Student.class);
		
		//使用student做一些操作
		//......
	}
}

2. @Mock 注解初始化 mock

除了上面 mock 靜態(tài)方法來(lái)創(chuàng)建模擬對(duì)象實(shí)例,還可以使用 openMocks 來(lái)初始化 mock 然后使用 @Mock 注解來(lái)更簡(jiǎn)單的創(chuàng)建模擬對(duì)象實(shí)例。

import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
import static org.mockito.Mockito.*;

public class MockTest {
    @Mock
    Student student; //使用 @Mock 注解來(lái)模擬一個(gè)student對(duì)象

    @Test
    public void whenNotUseMockAnnotation_thenCorrect() throws Exception {
		//初始化Mock,(以前低版本的寫(xiě)法是使用initMocks(this)現(xiàn)高版本中改方法已被廢棄,轉(zhuǎn)而使用openMocks(this)初始化)
		AutoCloseable closeable = MockitoAnnotations.openMocks(this);
	
		//使用mockedList做一些操作
		//......
		
		//關(guān)閉mock
		closeable.close();
	}
}

可以把初始化 Mock 和關(guān)閉 mock 的代碼放到 @BeforeEach 和 @AfterEach 注解的方法中更合適,這樣如果你有多個(gè)測(cè)試方法就不必每個(gè)測(cè)試方法中都再寫(xiě)一遍初始化和關(guān)閉Mock的代碼了:

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
import static org.mockito.Mockito.*;

public class MockTest {
    @Mock
    Student student;

    private AutoCloseable closeable;

    @BeforeEach
    void initService() {
        closeable = MockitoAnnotations.openMocks(this);

    }

    @AfterEach
    void closeService() throws Exception {
        closeable.close();
    }

    @Test
    public void whenNotUseMockAnnotation_thenCorrect() {
		//使用mockedList做一些操作
		//......
	
	}
}

3. 使用Mockito JUnit 5 擴(kuò)展來(lái)初始化 mock

除了上面兩種方式,還有一個(gè)用于JUnit 5的 Mockito 擴(kuò)展庫(kù),它初始化 mock 更加簡(jiǎn)單,一般用這種方式用的比較多,下文的所有示例都將采用這種方式。

先添加如下 mock 擴(kuò)展依賴(lài):

		<!-- 用于單元測(cè)試中使用@Mock注解時(shí)使用@ExtendWith(MockitoExtension.class)-->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>4.11.0</version>
            <scope>test</scope>
        </dependency>

在測(cè)試類(lèi)上面加上 @ExtendWith(MockitoExtension.class) 注解 ,然后使用 @Mock 注解修飾模擬對(duì)象即可:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class MockTest {

    @Mock
    Student student;
    
    @Test
    public void whenNotUseMockAnnotation_thenCorrect() {
		//...
	}
}

如果你測(cè)試類(lèi)里有多個(gè)測(cè)試方法,不想每個(gè)測(cè)試方法都共享模擬變量,還可以將模擬對(duì)象注入到方法參數(shù):

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class MockTest {

    @Test
    public void whenNotUseMockAnnotation_thenCorrect(@Mock Student student) {
		//...
	}
}

四、初始化mock后,mock對(duì)象會(huì)覆蓋掉整個(gè)被mock的對(duì)象

初始化mock后,mock對(duì)象會(huì)覆蓋掉整個(gè)被mock的對(duì)象,當(dāng)你直接調(diào)用mock實(shí)例對(duì)象的方法不會(huì)走真實(shí)的方法,只會(huì)返回默認(rèn)值(返回null或者空集合,或者0等基本類(lèi)型的值)。

舉個(gè)例子:

    @Mock
    Student student ;
    @Mock
    List<String> list ;

    @Test
    public void whenThenCorrect()  {
        student.setId(1);
        System.out.println(student.getId()); //輸出0
        list.add("a");
        System.out.println(list.get(0)); //輸出null
        System.out.println(list.size()); //輸出0
	}

所以對(duì)于初始化之后的 mock 實(shí)例對(duì)象是不能直接調(diào)用其方法進(jìn)行返回東西的,要讓 mock 實(shí)例對(duì)象返回東西需要用 when…thenReturn 模擬方法返回值。

五、when…thenReturn 模擬方法返回值

(1) 對(duì)于有返回值的方法

when(mock.someMethod(arg1, arg2, …)).thenReturn(value)用于設(shè)置模擬的實(shí)例方法返回值,設(shè)置后再調(diào)用該方法不會(huì)運(yùn)行實(shí)例方法里的邏輯,將直接返回模擬的值:

    @Mock
    Student student;

    @Test
    public void whenThenCorrect() {
		//設(shè)置 student.getName("張三",1)的返回值是"模擬的張三",后面的代碼如果調(diào)用 student.getName("張三",1)將直接返回"模擬的張三",不會(huì)去執(zhí)行 student.getName()里的邏輯
        when(student.getName("張三",1)).thenReturn("模擬的張三");
		//調(diào)用student.getName("張三",1)斷言為 "張三"
        assertEquals("模擬的張三", student.getName("張三",1));
	}

可以在 thenReturn(value1, value2, …) 里設(shè)置連續(xù)設(shè)定返回值,第一次調(diào)用時(shí)返回 value1,第二次返回value2:

    @Mock
    Student student;

    @Test
    public void whenThenCorrect()  {
        when(student.getName("張三",1)).thenReturn("張三","李四");
        assertEquals("張三", student.getName("張三",1));
        assertEquals("李四", student.getName("張三",1));
	}

(2) 對(duì)于無(wú)返回值的方法

對(duì)于無(wú)返回值的方法使用 doNothing().when(mock).someMethod(arg1, arg2, …)來(lái)模擬

    @Mock
    Student student;

    @Test
    public void whenThenCorrect()  {
        doNothing().when(student).sayHello("張三");
        student.sayHello("張三");
	}

注意:
對(duì)于 static 、 final 、private修飾的方法和equals()、hashCode()方法, Mockito 無(wú)法對(duì)其進(jìn)行when(…).thenReturn(…) 操作。

六、參數(shù)化匹配器

    @Mock
    Student student;

    @Test
    public void whenThenCorrect() {
        when(student.getName("張三",1)).thenReturn("模擬的張三");
        assertEquals("模擬的張三", student.getName("張三",1));
	}

在上面 when(mock.someMethod(arg1, arg2, …)).thenReturn(value) 里,我們所有的參數(shù) arg1、arg2 都是寫(xiě)死的,就像 student.getName(“張三”,1)這樣,這樣當(dāng)調(diào)用的時(shí)候也要寫(xiě)死了。

我們可以用參數(shù)化匹配器來(lái)優(yōu)化下:

(1) mockito 提供了很多參數(shù)匹配器

如:anyInt()、anyString()、anyDouble()、anyList()、anyMap()等

    @Mock
    Student student;

    @Test
    public void whenThenCorrect() {
		//使用參數(shù)化匹配器 anyString()和 anyInt()
        when(student.getName(anyString(),anyInt())).thenReturn("張三","李四");
        //調(diào)用student.getName 隨便傳入兩個(gè)參數(shù),斷言為 "張三"
        assertEquals("張三", student.getName("aa",12));
		//調(diào)用student.getName 隨便傳入兩個(gè)參數(shù),斷言為 "李四"
        assertEquals("李四", student.getName("bb",12));
	}

(2) 使用參數(shù)匹配器時(shí),方法里所有參數(shù)都應(yīng)使用匹配器。

例如下面的寫(xiě)法就是錯(cuò)的:

	when(student.getName(anyString(),1)).thenReturn("張三","李四");

如果要為參數(shù)使用特定值,則可以使用eq()方法:

    @Mock
    Student student;

    @Test
    public void whenThenCorrect() {
		//使用參數(shù)化匹配器 anyString()和 anyInt()
        when(student.getName(anyString(),eq(1))).thenReturn("張三","李四");
        //調(diào)用student.getName 第一個(gè)參數(shù)隨便傳入,第二個(gè)參數(shù)要傳1。斷言為 "張三"
        assertEquals("張三", student.getName("aa",1));
		//調(diào)用student.getName 第一個(gè)參數(shù)隨便傳入,第二個(gè)參數(shù)要傳1。斷言為 "李四"
        assertEquals("李四", student.getName("bb",1));
	}

六、when…thenThrow 模擬異常拋出

使用 when(mock.someMethod()).thenThrow(Exception()) 模擬方法異常拋出

	@Mock
    Student student;

    @Test
    public void exceptionCorrect()  {
	    //模擬當(dāng)調(diào)用 student.getName 時(shí)拋出 RuntimeException 異常
        when(student.getName(anyString(),anyInt())).thenThrow(new RuntimeException());
        //將拋出 RuntimeException 異常
        student.getName("aa",1);
	}

七、verify 驗(yàn)證方法是否被調(diào)用

有些時(shí)候,測(cè)試并不關(guān)心返回結(jié)果,而是關(guān)心方法是否被正確的參數(shù)調(diào)用過(guò),這時(shí)候就應(yīng)該使用驗(yàn)證方法了。

verify 用于驗(yàn)證模擬的實(shí)例方法是否被調(diào)用,若沒(méi)有調(diào)用則驗(yàn)證失敗,就報(bào)錯(cuò)提示:

    @Mock
    Student student;

    @Test
    public void verifyCorrect()  {
        when(student.getName(anyString(),anyInt())).thenReturn("張三");
        assertEquals("張三", student.getName("aa",1));
		// 驗(yàn)證模擬的 student 實(shí)例其 getName 方法是否被調(diào)用過(guò)
		verify(student).getName(anyString(),anyInt());
	}

verify 還可以使用 times 來(lái)驗(yàn)證方法調(diào)用的次數(shù),若實(shí)際調(diào)用次數(shù)和預(yù)期的不符合,就報(bào)錯(cuò)提示:

    @Mock
    Student student;

    @Test
    public void verifyCorrect()  {
       when(student.getName(anyString(),eq(1))).thenReturn("張三","李四");
        assertEquals("張三", student.getName("aa",1));
        assertEquals("李四", student.getName("bb",1));
        //驗(yàn)證student.getName("aa",1)調(diào)用了1次
        verify(student,times(1)).getName("aa",1);
        //驗(yàn)證student.getName("bb",1)調(diào)用了1次
        verify(student,times(1)).getName("bb",1);
        //驗(yàn)證student.getName 總的調(diào)用了2次
        verify(student,times(2)).getName(anyString(),eq(1));
	}

八、Spy 運(yùn)行真實(shí)方法

有些時(shí)候我們不想對(duì)一個(gè)對(duì)象進(jìn)行 mock,但是我們想判斷一個(gè)普通對(duì)象的方法有沒(méi)有被調(diào)用過(guò),那你可以使用 Spy 來(lái)監(jiān)測(cè)對(duì)象,然后用 verify 來(lái)驗(yàn)證方法有沒(méi)有被調(diào)用。

(1)使用Spy方法

    @Test
    public void spyCorrect() {
		//使用 spy 方法 監(jiān)測(cè) spyList
        List<String> spyList = spy(new ArrayList<>());
        spyList.add("one");
        spyList.add("two");

		//驗(yàn)證上面有沒(méi)有調(diào)用add("one")方法
        verify(spyList).add("one");
        assertEquals(2, spyList.size());
        assertEquals("one", spyList.get(0));
        assertEquals("two", spyList.get(1));

        //size()和get(0)方法被模擬了返回值就不會(huì)去執(zhí)行其真實(shí)方法,get(1)沒(méi)被模擬會(huì)調(diào)用其真實(shí)方法返回值
        when(spyList.size()).thenReturn(100);
        when(spyList.get(0)).thenReturn("aa");
        assertEquals(100, spyList.size());
        assertEquals("aa", spyList.get(0));
        assertEquals("two", spyList.get(1));
	}

(2)使用 @Spy 注解

除了上面使用 Spy 方法,你也可以使用 @Spy 注解達(dá)到一樣的效果:

    @Spy
    List<String> spyList = new ArrayList<>();
	
    @Test
    public void spyCorrect() {
        spyList.add("one");
        spyList.add("two");

		//驗(yàn)證上面有沒(méi)有調(diào)用add("one")方法
        verify(spyList).add("one");
        assertEquals(2, spyList.size());
        assertEquals("one", spyList.get(0));
        assertEquals("two", spyList.get(1));

        //size()和get(0)方法被模擬了返回值就不會(huì)去執(zhí)行其真實(shí)方法,get(1)沒(méi)被模擬會(huì)調(diào)用其真實(shí)方法返回值
        when(spyList.size()).thenReturn(100);
        when(spyList.get(0)).thenReturn("aa");
        assertEquals(100, spyList.size());
        assertEquals("aa", spyList.get(0));
        assertEquals("two", spyList.get(1));
	}

九、@InjectMocks 注解解決依賴(lài)

上面第四點(diǎn)提到,初始化 mock 后,直接調(diào)用mock實(shí)例對(duì)象的方法不會(huì)走真實(shí)的方法,只會(huì)返回默認(rèn)值。

但是有些時(shí)候我們不想直接 mock 模擬對(duì)象,我們想實(shí)際的運(yùn)行對(duì)象的方法又讓它返回一個(gè)模擬值,但是這個(gè)對(duì)象的方法里又依賴(lài)了其他的對(duì)象。這個(gè)時(shí)候就可以使用 @InjectMocks 注解了。

@InjectMocks 創(chuàng)建一個(gè)類(lèi)的實(shí)例,并將使用 @Mock 注解創(chuàng)建的 mock 注入到這個(gè)實(shí)例中。

假設(shè)有 DatabaseDAO、NetworkDAO、MainClass 三個(gè)類(lèi),其中 MainClass 類(lèi)中的 save 方法需要用到 DatabaseDAO、NetworkDAO 。

  public class DatabaseDAO {
    public String save(String fileName) {
        System.out.println("Saved in database");
        return "Saved in database Ok";
    }
} 
public class NetworkDAO {
    public String save(String fileName) {
        System.out.println("Saved in network location");
        return "Saved in network Ok";
    }
} 
public class MainClass {
    DatabaseDAO database;
    NetworkDAO network;

    public boolean save(String fileName) {
        String databaseResule = database.save(fileName);
        System.out.println("Saved in database in Main class, "+databaseResule);

        String netWorkResule =  network.save(fileName);
        System.out.println("Saved in network in Main class, "+netWorkResule);

        return false;
    }
}

單元測(cè)試:

@ExtendWith(MockitoExtension.class)
public class MainClassTest {

    @InjectMocks
	@Spy //加上@Spy 注解防止mock多線(xiàn)程運(yùn)行報(bào)錯(cuò)
    MainClass mainClass;

    @Mock
    DatabaseDAO dependentClassOne;

    @Mock
    NetworkDAO dependentClassTwo;

    @Test
    public void injectMocksTest1() {
		//不使用when..thenReturn模擬返回值,調(diào)用方法執(zhí)行后將返回真實(shí)返回值
        assertFalse(mainClass.save("temp.txt"));
        verify(mainClass).save("temp.txt");
    }

    @Test
    public void injectMocksTest2() {
        when(mainClass.save("temp.txt")).thenReturn(true);
		//使用when..thenReturn模擬返回值,調(diào)用方法執(zhí)行后將返回模擬返回值
        assertTrue(mainClass.save("temp.txt"));
        verify(mainClass).save("temp.txt");
    }
}

運(yùn)行此單元測(cè)試,輸出結(jié)果:

Saved in database in Main class, null
Saved in network in Main class, null

上面沒(méi)對(duì) dependentClassOne 和 dependentClassTwo 的 save 方法進(jìn)行返回值模擬,所以默認(rèn)返回了 null , 下面對(duì)他們模擬下返回值:

@ExtendWith(MockitoExtension.class)
public class MainClassTest {

    @InjectMocks
	@Spy //加上@Spy 注解防止mock多線(xiàn)程運(yùn)行報(bào)錯(cuò)
    MainClass mainClass;

    @Mock
    DatabaseDAO dependentClassOne;

    @Mock
    NetworkDAO dependentClassTwo;

    @Test
    public void injectMocksTest2() {
        when(dependentClassOne.save(anyString())).thenReturn("aa");
        when(dependentClassTwo.save(anyString())).thenReturn("bb");
        when(mainClass.save("temp.txt")).thenReturn(true);
        assertTrue(mainClass.save("temp.txt"));
        verify(mainClass).save("temp.txt");
    }
}

運(yùn)行此單元測(cè)試,輸出結(jié)果:

Saved in database in Main class, aa
Saved in network in Main class, bb

參考:
Mockito Tutorial文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-610043.html

到了這里,關(guān)于JUnit 5單元測(cè)試(三)—— Mockito 模擬的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Junit4 + Mockito進(jìn)行單元測(cè)試實(shí)戰(zhàn)案例

    Junit4 + Mockito進(jìn)行單元測(cè)試實(shí)戰(zhàn)案例

    ? 實(shí)戰(zhàn)代碼案例: ??????????? 注意:idea2021.3.3之前的版本都搜索不到這個(gè)插件。 使用TestMe自動(dòng)生成單元測(cè)試代碼: 不是自動(dòng)化執(zhí)行的單元測(cè)試都是無(wú)意義的,項(xiàng)目中那么多單測(cè),難道一個(gè)一個(gè)點(diǎn)嗎? 引入maven-surefire-plugin插件用于自動(dòng)化執(zhí)行單測(cè)。 include里表

    2024年02月16日
    瀏覽(21)
  • 單元測(cè)試編寫(xiě)最佳實(shí)踐(ChatGPT+Mockito+JUnit)

    單元測(cè)試編寫(xiě)最佳實(shí)踐(ChatGPT+Mockito+JUnit)

    基于 springboot 微服務(wù)架構(gòu)給單元測(cè)試帶來(lái)的問(wèn)題: springboot 單元測(cè)試啟動(dòng)家長(zhǎng)過(guò)程非常緩慢,后期服務(wù)啟動(dòng)達(dá)到分鐘級(jí),非常影響效率 服務(wù)之間相互依賴(lài)非常嚴(yán)重,單元測(cè)試的運(yùn)行非常依賴(lài)其它服務(wù)穩(wěn)定性 第三方服務(wù)和中間件,測(cè)試過(guò)程產(chǎn)生大量垃圾數(shù)據(jù),污染環(huán)境,非常

    2024年02月09日
    瀏覽(39)
  • SpringBoot單元測(cè)試--Mockito+Junit5框架使用

    SpringBoot單元測(cè)試--Mockito+Junit5框架使用

    作為程序員為了提前發(fā)現(xiàn)代碼bug,優(yōu)化代碼; 通常我們寫(xiě)完某個(gè)功能模塊代碼后都需要寫(xiě)單元測(cè)試對(duì)代碼塊進(jìn)行測(cè)試(特別是敏捷開(kāi)發(fā)中);Java項(xiàng)目最常用的單元測(cè)試框架即為Junit(目前最新版本為Junit5),SpringBoot本身也整合了該框架。在寫(xiě)單元測(cè)試時(shí)代碼塊中的調(diào)到第三方接口方

    2024年02月02日
    瀏覽(23)
  • 深度揭秘JUnit5與Mockito的單元測(cè)試神秘面紗

    深度揭秘JUnit5與Mockito的單元測(cè)試神秘面紗

    在今天的學(xué)習(xí)中,我們將深入研究 JUnit 和Mockito,這是 Java 開(kāi)發(fā)中最強(qiáng)大的 單元測(cè)試 工具之一。通過(guò)學(xué)習(xí)如何編寫(xiě)清晰、高效的單元測(cè)試,我們將揭開(kāi)單元測(cè)試的神秘面紗,助力你在項(xiàng)目中寫(xiě)出更健壯的代碼。 提示: 今天的代碼是在第九天代碼的基礎(chǔ)上進(jìn)行開(kāi)發(fā),我們將為

    2024年02月02日
    瀏覽(33)
  • SpringBoot 實(shí)戰(zhàn):JUnit5+MockMvc+Mockito 做好單元測(cè)試

    SpringBoot 實(shí)戰(zhàn):JUnit5+MockMvc+Mockito 做好單元測(cè)試

    因?yàn)槔^承了 spring-boot-starter-parent ,所以我們依賴(lài)的 spring-boot-starter-test 不需要寫(xiě)具體的版本,可以直接集成父級(jí)的版本定義。其中, spring-boot-starter-web 是用于提供 REST API 的 web 容器, spring-boot-starter-test 可以提供各種測(cè)試框架的, spring-boot-maven-plugin 是將 SpringBoot 應(yīng)用打包為

    2024年04月15日
    瀏覽(28)
  • Spring Boot使用JUnit和Mockito進(jìn)行Service層單元測(cè)試

    ??在平時(shí)的開(kāi)發(fā)當(dāng)中,一個(gè)項(xiàng)目往往包含了大量的方法,可能有成千上萬(wàn)個(gè)。如何去保證這些方法產(chǎn)生的結(jié)果是我們想要的呢?那么在SpringBoot項(xiàng)目中我們是如何對(duì)Service層的方法進(jìn)行測(cè)試的呢? ??單元測(cè)試是一種軟件測(cè)試方法,用于測(cè)試代碼的最小可測(cè)試單元。在Java開(kāi)發(fā)

    2024年02月03日
    瀏覽(23)
  • Spring Boot與微服務(wù)測(cè)試:JUnit和Mockito的單元和集成測(cè)試實(shí)踐

    Spring Boot與微服務(wù)測(cè)試:JUnit和Mockito的單元和集成測(cè)試實(shí)踐

    微服務(wù)架構(gòu)的流行使得測(cè)試變得更為重要。在Spring Boot應(yīng)用中,使用JUnit和Mockito進(jìn)行單元和集成測(cè)試是一種常見(jiàn)的實(shí)踐。本文將深入探討如何利用這兩個(gè)測(cè)試框架,確保Spring Boot微服務(wù)的可靠性和穩(wěn)定性。 單元測(cè)試 1.1 JUnit簡(jiǎn)介 JUnit是Java中最為流行的單元測(cè)試框架之一,它提供

    2024年02月21日
    瀏覽(102)
  • 基于Junit4+Mockito+PowerMock實(shí)現(xiàn)Controller+Service的單元測(cè)試

    基于Junit4+Mockito+PowerMock實(shí)現(xiàn)Controller+Service的單元測(cè)試

    一 導(dǎo)入的依賴(lài) 二 依賴(lài)版本 三 controller測(cè)試示例代碼 ? ? ? controller ? ? ? ? controllerTest ? ? ? ? 測(cè)試結(jié)果:覆蓋率100% ? ? ? ? 帶異常的Controller ? ? ? ? 帶異常提示的ControllerTest ? ? ? ? 測(cè)試結(jié)果,覆蓋率100% ? 三 service測(cè)試示例代碼 ? ? ? ? service ? ? ? ? serviceTest ???

    2024年02月14日
    瀏覽(28)
  • springboot項(xiàng)目使用Junit5 + mockito + jacoco 實(shí)現(xiàn)單元測(cè)試以及代碼覆蓋率檢查

    在創(chuàng)建springboot項(xiàng)目時(shí)會(huì)默認(rèn)添加spring-boot-starter-test依賴(lài),其中已經(jīng)包含了junit、mockito依賴(lài),根據(jù)springboot版本的不同junit和mockito的版本也會(huì)有所不同 先說(shuō)一下各自功能: junit只說(shuō)一點(diǎn),junt4和junit5的注解不同,使用方式略有差異,其他不贅述了,基本用法都懂。 mockito是mock的

    2023年04月23日
    瀏覽(33)
  • mockito+junit 單元測(cè)試 測(cè)試私有方法利用反射去調(diào)用提升覆蓋率 反射調(diào)用時(shí)傳入?yún)?shù)為 null

    今天公司安排我寫(xiě)單元測(cè)試 因?yàn)橐ㄟ^(guò)三級(jí)認(rèn)證 公司要求是覆蓋率必須達(dá)到100% 而在寫(xiě)單元測(cè)試的時(shí)候 對(duì)于是否要測(cè)試私有方法一直是一個(gè)爭(zhēng)議 公司規(guī)范 對(duì)私有方法也進(jìn)行測(cè)試 代碼如下: JudgeUtils 是公司封裝的一個(gè)工具類(lèi) 讓我們看看 isNull 方法的內(nèi)部 代碼如下: 我現(xiàn)在需

    2024年02月11日
    瀏覽(28)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包