1. 程式人生 > >JAVA 單元測試總結

JAVA 單元測試總結

單元測試的重要性這裡就不說了,直接進入正題。很多程式設計師不喜歡寫單元測試,導致專案經常會花很多時間去debug,這完全得不償失。對關鍵方法進行單元測試,可以在早期業務邏輯還沒那麼複雜的時候,儘快排除癥結。

在dao,manager,server,web這樣的分層專案中,通常單元測試是要寫在server層的,因為server層可以測的最多。本文中不介紹單元測試的原理,只是介紹單元測試最常用的斷言和Jmockit的用法,可以應付業務開發中絕大部分單元測試。

首先新增maven依賴

<dependencie>
    <dependency>
         <groupId
>
junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId
>
<version>3.2.9.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>org.jmockit</groupId> <artifactId>jmockit</artifactId> <version>1.24</version> <scope
>
test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.8.4</version> <scope>test</scope> </dependency> </dependencie>

1 BaseTest.java

server層新建test包,在IDEA中標記為綠色,這個裡面寫Before和After,如果不需要,就空在這裡即可。其它具體的測試類要繼承BaseTest.java。

這裡寫圖片描述

package com.sf.sfpp.notice.test;

import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/test-service.xml" })
public class BaseTest  extends AbstractTransactionalJUnit4SpringContextTests {
    @Before
    public void init(){
    }
    @After
    public void print(){
    }
}

2 assert斷言

使用assert斷言是常用的單元測試方法之一。其本質是將方法的返回結果與預期值進行比較,相等則結果為綠色(單元測試通過),反之為紅色(單元測試未通過)。

比方說,我們在Manager層有一個類,UserHistoryManager,裡面有個方法是根據ID刪除使用者操作歷史

@Autowired
private UserHistoryMapper userHistoryMapper;

public int deleteUserHistoryById(int userHistoryId){
    return userHistoryMapper.deleteUserHistoryById(userHistoryId);
}

現在想要對這個方法進行單元測試,在server層的test下面的impl資料夾中新建一個TestUserHistoryManager類,依舊如第一張圖所示,程式碼如下:

package com.sf.sfpp.notice.test.impl;

import com.sf.sfpp.notice.common.domain.UserHistory;
import com.sf.sfpp.notice.manager.UserHistoryManager;
import com.sf.sfpp.notice.test.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

public class TestUserHistoryManager extends BaseTest {
    @Autowired
    private UserHistoryManager userHistoryManager;

    @Test
    public void testDeleteUserHistoryById(){
        Assert.assertEquals(true,userHistoryManager.deleteUserHistoryById(4) > 0);
    }
}

3 Jmockit

有些方法要遠遠比上面的assert複雜,例如當你的方法中要新增一個物件到資料庫中,此時如何進行單元測試呢?

還是如第一張圖片所示,在test下面的impl資料夾中新建TestUserNotificationManager.java,測試一下UserHistoryManager中新增使用者歷史的方法。

package com.sf.sfpp.notice.test.impl;

import com.sf.sfpp.notice.common.domain.UserHistory;
import com.sf.sfpp.notice.manager.UserHistoryManager;
import com.sf.sfpp.notice.test.BaseTest;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class TestUserNotificationManager extends BaseTest {
    @Autowired
    private UserHistoryManager userHistoryManager;

    @Test
    public void testAddUserHistory(){
        UserHistory userHistory = mock(UserHistory.class);
        when(userHistory.getAction()).thenReturn("balabala");
        when(userHistory.getTargetId()).thenReturn("balabala");
        when(userHistory.getUserId()).thenReturn(43);
        when(userHistory.getTargetKind()).thenReturn("balabala");
        when(userHistory.getId()).thenReturn("balabala");
        Assert.assertTrue(userHistoryManager.addUserHistory(balabala));
    }

}

上面的方法相當於用Jmockit虛擬了一個UserHistory物件(使用者操作歷史),然後根據其中的每個屬性看返回值(字串屬性對應字串返回值,int屬性對應int返回值)。

在IDEA中點選方法名前面的綠色箭頭(ctrl+shift+F10)

單元測試只要看到下面的綠色條,就表示測試通過了。
這裡寫圖片描述