中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java單元測試Powermockito和Mockito使用的示例分析

發布時間:2021-09-08 13:34:48 來源:億速云 閱讀:193 作者:小新 欄目:開發技術

小編給大家分享一下Java單元測試Powermockito和Mockito使用的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

    依賴引入

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.8.9</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>

    PowerMockito的使用

    Mockito、EasyMock、JMock等比較流行Mock框架有個共同的缺點,都不能mock靜態、final、私有方法等,而PowerMock可以完美解決以上框架的不足,接下來讓我們看看無所不能的PowerMock是如何解決上述問題,我們先從一個實例來看,下面的代碼是需要單測的類,被測類中既有對Spring Bean的調用,同時又包含對Redis的靜態讀取,另外還有getInstance()單例類的使用,現在,我們一一來mock上述的外部類。

    被單測類(主要測試queryStudentScoreByKeyword方法)

    @Component
    public class StudentService {
    
        @Resource
        private StudentDao studentDao;
    
        public List<StudentBo> queryStudentScoreByKeyword(String name) {
            System.out.println("invoke StudentService.queryStudentScoreByKeyword ...");
    
            List<StudentBo> cacheList = RedisUtils.getArray(name, StudentBo.class);
            if (CollectionUtils.isNotEmpty(cacheList)) {
                return cacheList;
            }
            String keyword = processKeyword(name);
            List<Student> students = studentDao.queryStudentByKeyWord(keyword);
            List<Integer> ids = students.stream().map(Student::getId).collect(Collectors.toList());
            List<Person> personList = SchoolManageProxy.getInstance().queryPerson(ids);
    
            List<StudentBo> studentBos = CommonUtils.toBo(personList, students);
            // 高亮結果
            highlightResult(studentBos, name);
            // 緩存到Redis
            RedisUtils.setArray(name, studentBos, 10 * 60);
            return studentBos;
        }
    
        private String processKeyword(String name) {
            System.out.println("invoke StudentService.processKeyword ...");
            String newName = name;
            // do somethings
            return newName;
        }
    
        private void highlightResult(List<StudentBo> result, String name) {
            System.out.println("invoke StudentService.highlightResult ...");
            // do keyword highlight
        }
    
    }

    單測類

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({SchoolManageProxy.class, RedisUtils.class, StudentService.class})
    // @PowerMockIgnore({"javax.management.*", "javax.net.ssl.*"})
    @SuppressStaticInitializationFor({"cn.ganzhiqiang.ares.unittest.SchoolManageProxy"})
    public class StudentServiceTest {
    
        @Mock
        private StudentDao mockStudentDao;
    
        @InjectMocks
        private StudentService studentServiceUnderTest;
    
        @Before
        public void setUp() {
            initMocks(this);
        }
    
        @Test
        public void testQueryStudentScoreByKeyword() throws Exception {
            studentServiceUnderTest = PowerMockito.spy(studentServiceUnderTest);
            PowerMockito.mockStatic(RedisUtils.class);
            PowerMockito.mockStatic(SchoolManageProxy.class);
    
            // mock單例調用
            SchoolManageProxy mockSchoolManageProxy = PowerMockito.mock(SchoolManageProxy.class);
            PowerMockito.when(SchoolManageProxy.getInstance()).thenReturn(mockSchoolManageProxy);
            when(mockSchoolManageProxy.queryPerson(anyList())).thenReturn(Collections.emptyList());
    
            // mock掉對Redis的靜態調用
            PowerMockito.when(RedisUtils.getArray(eq("tom"), eq(StudentBo.class))).thenReturn(Collections.emptyList());
            // 顯示的mock掉靜態的void的方法(可以不mock)
            PowerMockito.doNothing().when(RedisUtils.class, "setArray", anyString(), anyList(), anyInt());
    
            // mock私有方法processKeyword
            PowerMockito.doReturn("tom").when(studentServiceUnderTest, "processKeyword", anyString());
    
            // 跳過私有方法highlightResult的執行
            PowerMockito.suppress(PowerMockito.method(StudentService.class, "highlightResult"));
    
            // 使用Mockito來mock服務的調用
            when(mockStudentDao.queryStudentByKeyWord(anyString())).thenReturn(Collections.emptyList());
    
            // Run the test
            final List<StudentBo> result = studentServiceUnderTest.queryStudentScoreByKeyword("tom");
    
        }
    }

    使用mockito來mock實例

    首選我們先用Mockito來mock對Spring Bean的調用,Mockito.mock可以mock一個實例,我們這里選用@Mock注解,效果是一樣的。

    // 使用Mockito來mock服務的調用 
    when(mockStudentDao.queryStudentByKeyWord(anyString())).thenReturn(Collections.emptyList());

    mock對Redis的靜態調用

    接下來我們使用PowerMock來mock對靜態方法的調用,注意需要將RedisUtils類,加入@PrepareForTest注解中,我們既mock了getArray方法,也mock了setArray方法,其實setArray不需要mock這里顯式的mock了

    PowerMockito.mockStatic(RedisUtils.class);
    // mock掉對Redis的靜態調用
    PowerMockito.when(RedisUtils.getArray(eq("tom"), eq(StudentBo.class))).thenReturn(Collections.emptyList());
    // 顯式的mock掉靜態的void的方法(可以不mock)
    PowerMockito.doNothing().when(RedisUtils.class, "setArray", anyString(), anyList(), anyInt());

    mock單例類

    mock單例類相對來說復雜一點,邏輯上先用Powermock mock出單例類,然后再給單例類的getInstance方法打樁,返回之前mock,再對mock類實際調用的方法打樁即可,代碼如下

    PowerMockito.mockStatic(SchoolManageProxy.class);
    // Powermock mock出單例類
    SchoolManageProxy mockSchoolManageProxy = PowerMockito.mock(SchoolManageProxy.class);
    // 給單例類的getInstance方法打樁
    
    PowerMockito.when(SchoolManageProxy.getInstance()).thenReturn(mockSchoolManageProxy);
    // 對mock類queryPerson的方法打樁
    when(mockSchoolManageProxy.queryPerson(anyList())).thenReturn(Collections.emptyList());

    mock私有方法

    可以看到queryStudentScoreByKeyword方法調用了該類的私有方法processKeyword,如果該方法耗時過長,使用powermock也可以mock該私有方法,需要注意的studentServiceUnderTest需要用spy()來mock

    // mock 實例
    // spy的標準是:如果不打樁,默認執行真實的方法,如果打樁則返回樁實現。
    studentServiceUnderTest = PowerMockito.spy(studentServiceUnderTest);
    // mock私有方法processKeyword
    // doReturn(...) when(...)不做真實調用,但是when(...) thenReturn(...)還是會真實調用原方法,只是返回了指定的結果
    PowerMockito.doReturn("tom").when(studentServiceUnderTest, "processKeyword", anyString());

    PowerMock跳過方法執行

    使用PowerMock也可以跳過私有方法的執行

    // 跳過私有方法highlightResult的執行
    PowerMockito.suppress(PowerMockito.method(StudentService.class, "highlightResult"));

    看完了這篇文章,相信你對“Java單元測試Powermockito和Mockito使用的示例分析”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    维西| 秀山| 海门市| 中宁县| 密山市| 蓝田县| 马边| 凌云县| 察雅县| 洪湖市| 高邑县| 南开区| 和平区| 东乡县| 偏关县| 尖扎县| 富平县| 新民市| 鹿邑县| 东宁县| 武平县| 聊城市| 天峨县| 正安县| 简阳市| 社会| 嘉黎县| 吉林省| 普兰店市| 资讯| 临西县| 河津市| 班玛县| 武宣县| 修武县| 焦作市| 正蓝旗| 离岛区| 湘潭市| 繁峙县| 正阳县|