07 Spring 單元測(cè)試(融合 Junit,輕松入門(mén))

轉(zhuǎn)載請(qǐng)注明來(lái)源 賴(lài)賴(lài)的博客

導(dǎo)語(yǔ)

學(xué)習(xí)妻柒,先知骨架扛拨,再豐羽翼,先知其然举塔,再知其所以然绑警。

要迅速解決問(wèn)題,首先要有一個(gè)自己的框架知識(shí)庫(kù)央渣,例如计盒,我知道Tomcat可以搭建web服務(wù)器,我知道Spring MVC可以構(gòu)件web項(xiàng)目芽丹,我知道Mybatis可以控制持久層...
這些是需要了解并且記在腦中的北启,至于詳細(xì)的東西,等用的時(shí)候可以詳細(xì)了解拔第,此博客專(zhuān)題連載的Spring系列咕村,就是送你一套框架知識(shí)庫(kù)
今天介紹單元測(cè)試,簡(jiǎn)單實(shí)例蚊俺,讓你知其然懈涛。

實(shí)例

項(xiàng)目工程目錄結(jié)構(gòu)和代碼獲取地址

獲取地址(版本Log將會(huì)注明每一個(gè)版本對(duì)應(yīng)的課程)

https://github.com/laiyijie/SpringLearning

目錄結(jié)構(gòu)

目錄結(jié)構(gòu)

運(yùn)行工程(與之前不同,請(qǐng)注意)

運(yùn)行方式
  • 右鍵HelloInterFaceTest.java
  • Run as
  • JUnit Test
運(yùn)行結(jié)果

init before every testcase
the 10 time to say userHello
clean after every testcase
init before every testcase
time:1480420925632 userHello
clean after every testcase

項(xiàng)目詳解

從HelloInterFaceTest.java入手(終于不是四行代碼的App.java啦)

HelloInterFaceTest.java

package me.laiyijie.demo.service;

import org.junit.After;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:root-context.xml" })
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HelloInterFaceTest {

    @Autowired
    private HelloInterface helloInterface;

    @Before
    public void init() {
        System.out.println("init before every testcase");
    }

    @After
    public void after() {
        System.out.println("clean after every testcase");
    }

    @Test
    public void TS0101_sayHello_normal() {

        int num = 10;

        String result = helloInterface.sayHello(num);
        
        System.out.println(result);
        
        String expect = "the " + num + " time to say userHello";
        
        assertEquals(expect, result);
    }

    @Test
    public void TS0201_sayHelloWithTime_normal() {
        
        String result = helloInterface.sayHelloWithTime();
        
        System.out.println(result);
    }
}  

代碼有點(diǎn)兒長(zhǎng)泳猬?莫慌批钠,長(zhǎng)代碼,一個(gè)套路得封,那就是疊磚埋心!讓我們仔細(xì)看看這塊磚

JUnit測(cè)試用例執(zhí)行過(guò)程概述

首先略過(guò)頭部,直接看類(lèi)里面的方法呛每,其中兩個(gè)函數(shù)分別被@Before@After注解踩窖,兩個(gè)函數(shù)被@Test注解。
我們仔細(xì)看一下運(yùn)行結(jié)果可以發(fā)現(xiàn)幾個(gè)函數(shù)的執(zhí)行順序如下所示:

  1. @Before 注解的函數(shù)先執(zhí)行
  2. @Test 注解的TS0101_sayHello_normal執(zhí)行
  3. @After 注解的函數(shù)執(zhí)行
  4. @Before 注解的函數(shù)先執(zhí)行
  5. @Test 注解的TS0201_sayHelloWithTime_normal執(zhí)行
  6. @After 注解的函數(shù)執(zhí)行

那么顯而易見(jiàn)的結(jié)論:

  • @Test注釋的函數(shù)會(huì)挨個(gè)執(zhí)行(我們稱(chēng)這個(gè)函數(shù)為測(cè)試用例
  • @Before注解的函數(shù)會(huì)在每個(gè)@Test注解的函數(shù)之 執(zhí)行(我們使用這個(gè)注解進(jìn)行測(cè)試用例前的初始化)
  • @After 注解的函數(shù)會(huì)在每個(gè)@Test注解的函數(shù)之 執(zhí)行(我們使用這個(gè)注解進(jìn)行測(cè)試用例后的清理)

下面詳細(xì)解讀其余部分:

import先略過(guò)晨横,只是一些依賴(lài)

之后從類(lèi)前面的注解開(kāi)始講解

Spring測(cè)試類(lèi)前注解含義(啟動(dòng)Spring測(cè)試環(huán)境)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:root-context.xml" })
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
  • @RunWith(SpringJUnit4ClassRunner.class) 提供了一個(gè)Spring的運(yùn)行環(huán)境洋腮,說(shuō)白了,就是可以在測(cè)試類(lèi)中使用@Autowired等Spring注解手形,例如代碼中的private HelloInterface helloInterface;就是使用@Autowired來(lái)注入啥供,你完全可以理解為是@Service
  • @ContextConfiguration({ "classpath:root-context.xml" }) 加載了root-context.xml(加載了才可以注入 UserServiceImpl實(shí)例嘛
  • @FixMethodOrder(MethodSorters.NAME_ASCENDING) 根據(jù)用例的函數(shù)名稱(chēng)升序執(zhí)行用例(很實(shí)用,但是非必須)

OK库糠,三個(gè)注解解決了Spring+JUnit單元測(cè)試環(huán)境的配置伙狐。

JUnit的三個(gè)注解涮毫,加上Spring Test環(huán)境的配置,測(cè)試用例就此簡(jiǎn)單起步贷屎。
而在測(cè)試用例中罢防,我們肯定不能通過(guò)System.out.println輸出到控制臺(tái)來(lái)進(jìn)行判斷(肉眼判斷輸出是否正確,很容易出現(xiàn)失誤)
在此我簡(jiǎn)單的介紹使用Assert類(lèi)提供的方法判斷輸出是否正確

assertequals唉侄,跟肉眼say goodbye

我們摘出這段代碼:

@Test
public void TS0101_sayHello_normal() {

    int num = 10;

    String result = helloInterface.sayHello(num);
    
    System.out.println(result);
    
    String expect = "the " + num + " time to say userHello";
    
    assertEquals(expect, result);
}  

其中這句話:

assertEquals(expect, result);

就這么簡(jiǎn)單咒吐,第一參數(shù)為期望輸出第二個(gè)參數(shù)為真實(shí)結(jié)果

  • 如果兩者相等(equals)属划,用例通過(guò)(JUnit測(cè)試條為綠色)
測(cè)試成功
  • 如果兩者不等恬叹,用例失敗(JUnit測(cè)試條為紅色)
測(cè)試失敗
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>me.laiyijie</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.2.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        
    </dependencies>
</project>

新增兩個(gè)Scope為test的依賴(lài)同眯,分別是

  • spring-test 提供@RunWith中的 SpringJUnit4ClassRunner.class 以及 @ContextConfiguration
  • junit 提供@RunWith绽昼,@After@Before须蜗,@Test

小結(jié):

  • JUnit運(yùn)行過(guò)程
    • 通過(guò)@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration({ "classpath:root-context.xml" })配置Spring單元測(cè)試環(huán)境硅确,使得
      1. 加載root-context.xml配置的ApplicationContext
      2. 使得HelloInterFaceTest(測(cè)試類(lèi))可以使用@Autowired裝載容器中的bean
    • 通過(guò)@Before實(shí)現(xiàn)測(cè)試用例運(yùn)行前初始化
    • 通過(guò)@Test定義測(cè)試用例并且挨個(gè)執(zhí)行
    • 通過(guò)@After實(shí)現(xiàn)測(cè)試用例完成后清理

測(cè)試用例這么好寫(xiě),何不多寫(xiě)幾個(gè)唠粥?你的代碼穩(wěn)定性會(huì)提升一個(gè)層次疏魏!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末停做,一起剝皮案震驚了整個(gè)濱河市晤愧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛉腌,老刑警劉巖官份,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異烙丛,居然都是意外死亡舅巷,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)河咽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)钠右,“玉大人,你說(shuō)我怎么就攤上這事忘蟹§浚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵媚值,是天一觀的道長(zhǎng)狠毯。 經(jīng)常有香客問(wèn)我,道長(zhǎng)褥芒,這世上最難降的妖魔是什么嚼松? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上献酗,老公的妹妹穿的比我還像新娘寝受。我一直安慰自己,他們只是感情好罕偎,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布羡蛾。 她就那樣靜靜地躺著,像睡著了一般锨亏。 火紅的嫁衣襯著肌膚如雪痴怨。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,696評(píng)論 1 312
  • 那天器予,我揣著相機(jī)與錄音浪藻,去河邊找鬼。 笑死乾翔,一個(gè)胖子當(dāng)著我的面吹牛爱葵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播反浓,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼萌丈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了雷则?” 一聲冷哼從身側(cè)響起辆雾,我...
    開(kāi)封第一講書(shū)人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎月劈,沒(méi)想到半個(gè)月后度迂,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猜揪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年惭墓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片而姐。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腊凶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拴念,到底是詐尸還是另有隱情钧萍,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布丈莺,位于F島的核電站划煮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏缔俄。R本人自食惡果不足惜弛秋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一器躏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蟹略,春花似錦登失、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至意敛,卻和暖如春馅巷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背草姻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工钓猬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人撩独。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓敞曹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親综膀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子澳迫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)剧劝,斷路器橄登,智...
    卡卡羅2017閱讀 134,716評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,867評(píng)論 6 342
  • 單元測(cè)試 單測(cè)定義 單元測(cè)試(Unit Testing)又稱(chēng)為模塊測(cè)試, 是針對(duì)程序模塊(軟件設(shè)計(jì)的最小單位)來(lái)進(jìn)...
    運(yùn)維開(kāi)發(fā)筆記閱讀 1,997評(píng)論 0 2
  • 注意事項(xiàng): 測(cè)試方法上必須使用@Test修飾 測(cè)試方法必須使用public void進(jìn)行修飾,不能帶任何參數(shù) 新建...
    魯克巴克詩(shī)閱讀 1,768評(píng)論 0 3
  • 又到了跳槽旺季,很多人都會(huì)有這樣那樣的困擾拌禾,當(dāng)你準(zhǔn)備好面試的時(shí)候取胎,你必須懂下面這些潛臺(tái)詞,并作出相應(yīng)的解決措施湃窍,才...
    左手維納斯閱讀 22,365評(píng)論 4 57