国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

第三十五章:SpringBoot與單元測(cè)試的小秘密

hikui / 2669人閱讀

摘要:本章目的基于平臺(tái)整合分別完成客戶端服務(wù)端的單元測(cè)試。在測(cè)試控制器內(nèi)添加了三個(gè)測(cè)試方法,我們接下來(lái)開(kāi)始編寫單元測(cè)試代碼。總結(jié)本章主要介紹了基于平臺(tái)的兩種單元測(cè)試方式,一種是在服務(wù)端采用注入方式將需要測(cè)試的或者注入到測(cè)試類中,然后調(diào)用方法即可。

單元測(cè)試對(duì)于開(kāi)發(fā)人員來(lái)說(shuō)是非常熟悉的,我們每天的工作也都是圍繞著開(kāi)發(fā)與測(cè)試進(jìn)行的,在最早的時(shí)候測(cè)試都是采用工具Debug模式進(jìn)行調(diào)試程序,后來(lái)Junit的誕生也讓程序測(cè)試發(fā)生了很大的變化。我們今天來(lái)講解下基于SpringBoot結(jié)合Junit怎么來(lái)完成單元測(cè)試

本章目的

基于SpringBoot平臺(tái)整合Junit分別完成客戶端服務(wù)端單元測(cè)試

構(gòu)建項(xiàng)目

我們首先使用idea工具創(chuàng)建一個(gè)SpringBoot項(xiàng)目,并且添加相關(guān)Web、MySQL、JPA依賴,具體pom.xml配置依賴內(nèi)容如下所示:

.../省略其他配置

        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
        
            com.alibaba
            druid
            1.0.31
        
        
        
            org.projectlombok
            lombok
        
        
        
            mysql
            mysql-connector-java
        

        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

    
.../省略其他配置
配置數(shù)據(jù)庫(kù)

我們本章的內(nèi)容需要訪問(wèn)數(shù)據(jù)庫(kù),我們先在src/main/resources下添加application.yml配置文件,對(duì)應(yīng)添加數(shù)據(jù)庫(kù)配置信息如下所示:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
    username: root
    password: 123456
    #最大活躍數(shù)
    maxActive: 20
    #初始化數(shù)量
    initialSize: 1
    #最大連接等待超時(shí)時(shí)間
    maxWait: 60000
    #打開(kāi)PSCache,并且指定每個(gè)連接PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    #通過(guò)connectionProperties屬性來(lái)打開(kāi)mergeSql功能;慢SQL記錄
    #connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 1 from dual
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    #配置監(jiān)控統(tǒng)計(jì)攔截的filters,去掉后監(jiān)控界面sql將無(wú)法統(tǒng)計(jì),"wall"用于防火墻
    filters: stat, wall, log4j
  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true

以上配置都是比較常用到,這里不做多解釋了,如果不明白可以去本文底部SpringBoot學(xué)習(xí)目錄文章內(nèi)找尋對(duì)應(yīng)的章節(jié)。

構(gòu)建實(shí)體

對(duì)應(yīng)數(shù)據(jù)庫(kù)內(nèi)的數(shù)據(jù)表來(lái)創(chuàng)建一個(gè)商品基本信息實(shí)體,實(shí)體內(nèi)容如下所示:

package com.yuqiyu.chapter35.bean;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

/**
 * 商品基本信息實(shí)體
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/9/13
 * Time:22:20
 * 碼云:http://git.oschina.net/jnyqy
 * ========================
 */
@Data
@Entity
@Table(name = "good_infos")
public class GoodInfoEntity implements Serializable
{
    //商品編號(hào)
    @Id
    @Column(name = "tg_id")
    @GeneratedValue
    private Integer tgId;

    //商品類型編號(hào)
    @Column(name = "tg_type_id")
    private Integer typeId;

    //商品標(biāo)題
    @Column(name = "tg_title")
    private String title;

    //商品價(jià)格
    @Column(name = "tg_price")
    private double price;

    //商品排序
    @Column(name = "tg_order")
    private int order;
}
構(gòu)建JPA

基于商品基本信息實(shí)體類創(chuàng)建一個(gè)JPA接口,該接口繼承JpaRepository接口完成框架通過(guò)反向代理模式進(jìn)行生成實(shí)現(xiàn)類,自定義JPA接口內(nèi)容如下所示:

package com.yuqiyu.chapter35.jpa;

import com.yuqiyu.chapter35.bean.GoodInfoEntity;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * 商品jpa
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/9/13
 * Time:22:23
 * 碼云:http://git.oschina.net/jnyqy
 * ========================
 */
public interface GoodInfoJPA
    extends JpaRepository
{
}
構(gòu)建測(cè)試控制器

下面我們開(kāi)始為單元測(cè)試來(lái)做準(zhǔn)備工作,先來(lái)創(chuàng)建一個(gè)SpringMVC控制器來(lái)處理請(qǐng)求,代碼如下所示:

package com.yuqiyu.chapter35.controller;

import com.yuqiyu.chapter35.bean.GoodInfoEntity;
import com.yuqiyu.chapter35.jpa.GoodInfoJPA;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * ===============================
 * Created with Eclipse.
 * User:于起宇
 * Date:2017/9/13
 * Time:18:37
 * 簡(jiǎn)書:http://www.jianshu.com/u/092df3f77bca
 * ================================
 */
@RestController
public class TestController
{
    //商品基本信息數(shù)據(jù)接口
    @Autowired
    private GoodInfoJPA goodInfoJPA;

    /**
     * 查詢首頁(yè)內(nèi)容
     * @return
     */
    @RequestMapping(value = "/index")
    public String index(String name)
    {
        return "this is index page" + name;
    }

    /**
     * 查詢?nèi)可唐?     * @return
     */
    @RequestMapping(value = "/all")
    public List selectAll()
    {
        return goodInfoJPA.findAll();
    }

    /**
     * 查詢商品詳情
     * @param goodId
     * @return
     */
    @RequestMapping(value = "/detail",method = RequestMethod.GET)
    public GoodInfoEntity selectOne(Integer goodId)
    {
        return goodInfoJPA.findOne(goodId);
    }
}

我們?cè)跍y(cè)試控制內(nèi)注入了GoodInfoJPA,獲得了操作商品基本信息的數(shù)據(jù)接口代理實(shí)例,我們可以通過(guò)該代理實(shí)例去做一些數(shù)據(jù)庫(kù)操作,如上代碼selectAlldetail方法所示。
在測(cè)試控制器內(nèi)添加了三個(gè)測(cè)試MVC方法,我們接下來(lái)開(kāi)始編寫單元測(cè)試代碼。

編寫單元測(cè)試

在我們使用idea開(kāi)發(fā)工具構(gòu)建完成SpringBoot項(xiàng)目后,會(huì)自動(dòng)為我們添加spring-boot-starter-test依賴到pom.xml配置文件內(nèi),當(dāng)然也為我們自動(dòng)創(chuàng)建了一個(gè)測(cè)試類,該類內(nèi)一開(kāi)始是沒(méi)有過(guò)多的代碼的。
下面我們開(kāi)始基于該測(cè)試類進(jìn)行添加邏輯,代碼如下所示:

....//省略依賴導(dǎo)包
/**
 * 單元測(cè)試
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter35ApplicationTests {
    /**
     * 模擬mvc測(cè)試對(duì)象
     */
    private MockMvc mockMvc;

    /**
     * web項(xiàng)目上下文
     */
    @Autowired
    private WebApplicationContext webApplicationContext;

    /**
     * 商品業(yè)務(wù)數(shù)據(jù)接口
     */
    @Autowired
    private GoodInfoJPA goodInfoJPA;

    /**
     * 所有測(cè)試方法執(zhí)行之前執(zhí)行該方法
     */
    @Before
    public void before() {
        //獲取mockmvc對(duì)象實(shí)例
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
}

在上面測(cè)試代碼中我們從上面開(kāi)始講解下,其中@RunWith這里就不多做解釋了,我們最比較常用到的就是這個(gè)注解。

@SpringBootTest這個(gè)注解這里要強(qiáng)調(diào)下,這是SpringBoot項(xiàng)目測(cè)試的核心注解,標(biāo)識(shí)該測(cè)試類以SpringBoot方式運(yùn)行,該注解的源碼如下所示:

...//省略導(dǎo)包
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(SpringBootTestContextBootstrapper.class)
public @interface SpringBootTest {
    @AliasFor("properties")
    String[] value() default {};

    @AliasFor("value")
    String[] properties() default {};

    Class[] classes() default {};

    SpringBootTest.WebEnvironment webEnvironment() default SpringBootTest.WebEnvironment.MOCK;

    public static enum WebEnvironment {
        MOCK(false),
        RANDOM_PORT(true),
        DEFINED_PORT(true),
        NONE(false);

        private final boolean embedded;

        private WebEnvironment(boolean embedded) {
            this.embedded = embedded;
        }

        public boolean isEmbedded() {
            return this.embedded;
        }
    }
}

我們可以看到在@SpringBootTest注解源碼中最為重要的就是@BootstrapWith,該注解才是配置了測(cè)試類的啟動(dòng)方式,以及啟動(dòng)時(shí)使用實(shí)現(xiàn)類的類型。

測(cè)試index請(qǐng)求

MockMvc這個(gè)類是一個(gè)被final修飾的類型,該類無(wú)法被繼承使用。這個(gè)類是Spring為我們提供模擬SpringMVC請(qǐng)求的實(shí)例類,該類則是由MockMvcBuilders通過(guò)WebApplicationContext實(shí)例進(jìn)行創(chuàng)建的,初始化MockMvc實(shí)例我們可以看下before方法邏輯。到現(xiàn)在為止我們才是萬(wàn)事俱備就差編寫單元測(cè)試邏輯了,我們首先來(lái)編寫訪問(wèn)/index請(qǐng)求路徑的測(cè)試,具體測(cè)試代碼如下所示:

    /**
     * 測(cè)試訪問(wèn)/index地址
     * @throws Exception
     */
    @Test
    public void testIndex() throws Exception {
        MvcResult mvcResult = mockMvc
                .perform(// 1
                        MockMvcRequestBuilders.get("/index") // 2
                        .param("name","admin") // 3
                )
                .andReturn();// 4

        int status = mvcResult.getResponse().getStatus(); // 5
        String responseString = mvcResult.getResponse().getContentAsString(); // 6

        Assert.assertEquals("請(qǐng)求錯(cuò)誤", 200, status); // 7
        Assert.assertEquals("返回結(jié)果不一致", "this is index pageadmin", responseString); // 8
    }
MockMvc解析

我在上面代碼中進(jìn)行了標(biāo)記,我們按照標(biāo)記進(jìn)行講解,這樣會(huì)更明白一些:
1 perform方法其實(shí)只是為了構(gòu)建一個(gè)請(qǐng)求,并且返回ResultActions實(shí)例,該實(shí)例則是可以獲取到請(qǐng)求的返回內(nèi)容。
2 MockMvcRequestBuilders該抽象類則是可以構(gòu)建多種請(qǐng)求方式,如:PostGetPutDelete等常用的請(qǐng)求方式,其中參數(shù)則是我們需要請(qǐng)求的本項(xiàng)目的相對(duì)路徑,/則是項(xiàng)目請(qǐng)求的根路徑。
3 param方法用于在發(fā)送請(qǐng)求時(shí)攜帶參數(shù),當(dāng)然除了該方法還有很多其他的方法,大家可以根據(jù)實(shí)際請(qǐng)求情況選擇調(diào)用。
4 andReturn方法則是在發(fā)送請(qǐng)求后需要獲取放回時(shí)調(diào)用,該方法返回MvcResult 對(duì)象,該對(duì)象可以獲取到返回的視圖名稱、返回的Response狀態(tài)、獲取攔截請(qǐng)求的攔截器集合等。
5 我們?cè)谶@里就是使用到了第4步內(nèi)的MvcResult對(duì)象實(shí)例獲取的MockHttpServletResponse對(duì)象從而才得到的Status狀態(tài)碼。
6 同樣也是使用MvcResult實(shí)例獲取的MockHttpServletResponse對(duì)象從而得到的請(qǐng)求返回的字符串內(nèi)容。【可以查看rest返回的json數(shù)據(jù)】
7 使用Junit內(nèi)部驗(yàn)證類Assert判斷返回的狀態(tài)碼是否正常為200
8 判斷返回的字符串是否與我們預(yù)計(jì)的一樣。

測(cè)試商品詳情

直接上代碼吧,跟上面的代碼幾乎一致,如下所示:

/**
     * 測(cè)試查詢?cè)斍?     * @throws Exception
     */
    @Test
    public void testDetail() throws Exception
    {
        MvcResult mvcResult = mockMvc
                .perform(
                        MockMvcRequestBuilders.get("/detail")
                        .param("goodId","2")
                )
                .andReturn(); // 5

        //輸出經(jīng)歷的攔截器
        HandlerInterceptor[] interceptors = mvcResult.getInterceptors();
        System.out.println(interceptors[0].getClass().getName());

        int status = mvcResult.getResponse().getStatus(); // 6
        String responseString = mvcResult.getResponse().getContentAsString(); // 7
        System.out.println("返回內(nèi)容:"+responseString);
        Assert.assertEquals("return status not equals 200", 200, status); // 8
    }

上面唯一一個(gè)部分需要解釋下,在上面測(cè)試方法內(nèi)輸出了請(qǐng)求經(jīng)歷的攔截器,如果我們配置了多個(gè)攔截器這里會(huì)根據(jù)先后順序?qū)懭氲綌r截器數(shù)組內(nèi),其他的MockMvc測(cè)試方法以及參數(shù)跟上面測(cè)試方法一致。

測(cè)試添加

在測(cè)試類聲明定義全局字段時(shí),我們注入了GoodInfoJPA實(shí)例,當(dāng)然單元測(cè)試也不僅僅是客戶端也就是使用MockMvc方式進(jìn)行的,我們也可以直接調(diào)用JPAService進(jìn)行直接測(cè)試。下面我們來(lái)測(cè)試下商品基本信息的添加,代碼如下所示:

/**
     * 測(cè)試添加商品基本信息
     */
    @Test
    public void testInsert()
    {
        /**
         * 商品基本信息實(shí)體
         */
        GoodInfoEntity goodInfoEntity = new GoodInfoEntity();
        goodInfoEntity.setTitle("西紅柿");
        goodInfoEntity.setOrder(2);
        goodInfoEntity.setPrice(5.82);
        goodInfoEntity.setTypeId(1);
        goodInfoJPA.save(goodInfoEntity);
        /**
         * 測(cè)試是否添加成功
         * 驗(yàn)證主鍵是否存在
         */
        Assert.assertNotNull(goodInfoEntity.getTgId());
    }

在上面代碼中并沒(méi)有什么特殊的部分,是我們?cè)谑褂?b>Data JPA時(shí)用到的save方法用于執(zhí)行添加,在添加完成后驗(yàn)證主鍵的值是否存在,NotNull時(shí)證明添加成功。

測(cè)試刪除

與添加差別不大,代碼如下所示:

    /**
     * 測(cè)試刪除商品基本信息
     */
    @Test
    public void testDelete()
    {
        //根據(jù)主鍵刪除
        goodInfoJPA.delete(3);
        
        //驗(yàn)證數(shù)據(jù)庫(kù)是否已經(jīng)刪除
        Assert.assertNull(goodInfoJPA.findOne(3));
    }

在上面代碼中,我們根據(jù)主鍵的值進(jìn)行刪除商品的基本信息,執(zhí)行刪除完成后調(diào)用selectOne方法查看數(shù)據(jù)庫(kù)內(nèi)是否已經(jīng)不存在該條數(shù)據(jù)了。

總結(jié)

本章主要介紹了基于SpringBoot平臺(tái)的兩種單元測(cè)試方式,一種是在服務(wù)端采用Spring注入方式將需要測(cè)試的JPA或者Service注入到測(cè)試類中,然后調(diào)用方法即可。另外一種則是在客戶端采用MockMvc方式測(cè)試Web請(qǐng)求,根據(jù)傳遞的不用參數(shù)以及請(qǐng)求返回對(duì)象反饋信息進(jìn)行驗(yàn)證測(cè)試。

本章代碼已經(jīng)上傳到碼云:
網(wǎng)頁(yè)地址:http://git.oschina.net/jnyqy/lessons
Git地址:https://git.oschina.net/jnyqy/lessons.git
SpringBoot相關(guān)系列文章請(qǐng)?jiān)L問(wèn):目錄:SpringBoot學(xué)習(xí)目錄
QueryDSL相關(guān)系列文章請(qǐng)?jiān)L問(wèn):QueryDSL通用查詢框架學(xué)習(xí)目錄
SpringDataJPA相關(guān)系列文章請(qǐng)?jiān)L問(wèn):目錄:SpringDataJPA學(xué)習(xí)目錄
感謝閱讀!
歡迎加入QQ技術(shù)交流群,共同進(jìn)步。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/67635.html

相關(guān)文章

  • 三十四章:SpringBoot配置類WebMvcConfigurerAdapter

    摘要:本章目標(biāo)繼承采用形式實(shí)現(xiàn)個(gè)性化配置定制。本章代碼已經(jīng)上傳到碼云網(wǎng)頁(yè)地址地址相關(guān)系列文章請(qǐng)?jiān)L問(wèn)目錄學(xué)習(xí)目錄相關(guān)系列文章請(qǐng)?jiān)L問(wèn)通用查詢框架學(xué)習(xí)目錄相關(guān)系列文章請(qǐng)?jiān)L問(wèn)目錄學(xué)習(xí)目錄感謝閱讀歡迎加入技術(shù)交流群,共同進(jìn)步。 WebMvcConfigurerAdapter配置類其實(shí)是Spring內(nèi)部的一種配置方式,采用JavaBean的形式來(lái)代替?zhèn)鹘y(tǒng)的xml配置文件形式進(jìn)行針對(duì)框架個(gè)性化定制,下面我...

    springDevBird 評(píng)論0 收藏0
  • #yyds干貨盤點(diǎn)#安全管理制度管理辦法范文

    摘要:第四章安全管理制度發(fā)布第十條安全管理制度必須以正式文件的形式發(fā)布施行。第十一條安全管理制度由信息安全管理小組制訂,信息安全領(lǐng)導(dǎo)小組審批發(fā)布。第二十條安全管理制度的修改與廢止須經(jīng)信息安全領(lǐng)導(dǎo)組織審批確認(rèn),信息安全管理部門備案。 字?jǐn)?shù) 3610閱讀 760評(píng)論 0贊 3《xxxx安全管理制度匯編》****制度管理辦法****文...

    duan199226 評(píng)論0 收藏0
  • 第二五章SpringBoot添加支持CORS跨域訪問(wèn)

    摘要:本章目標(biāo)基于項(xiàng)目搭建可以站外請(qǐng)求訪問(wèn)的跨域資源服務(wù)器。允許所有的請(qǐng)求域名訪問(wèn)我們的跨域資源,可以固定單條或者多條內(nèi)容,如,只有百度可以訪問(wèn)我們的跨域資源。 CORS(Cross-Origin Resource Sharing)跨域資源共享,是一個(gè)W3C標(biāo)準(zhǔn),它允許瀏覽器向跨域服務(wù)器發(fā)送Ajax請(qǐng)求,打破了Ajax只能訪問(wèn)本站內(nèi)的資源限制,CORS在很多地方都有被使用,微信支付的JS支付...

    simpleapples 評(píng)論0 收藏0
  • [系統(tǒng)安全] 三十五.Procmon工具基本用法及文件進(jìn)程、注冊(cè)表查看

    摘要:本文將分享軟件基本用法及文件進(jìn)程注冊(cè)表查看,這是一款微軟推薦的系統(tǒng)監(jiān)視工具,功能非常強(qiáng)大可用來(lái)檢測(cè)惡意軟件。可以幫助使用者對(duì)系統(tǒng)中的任何文件注冊(cè)表操作進(jìn)行監(jiān)視和記錄,通過(guò)注冊(cè)表和文件讀寫的變化,有效幫助診斷系統(tǒng)故障或發(fā)現(xiàn)惡意軟件病毒及木馬。 ...

    kk_miles 評(píng)論0 收藏0
  • 三十六章:基于SpringBoot架構(gòu)重寫SpringMVC請(qǐng)求參數(shù)裝載

    摘要:本章目標(biāo)根據(jù)項(xiàng)目定制參數(shù)狀態(tài)并了解的裝載過(guò)程以及實(shí)現(xiàn)方式。創(chuàng)建測(cè)試控制器創(chuàng)建名為的控制器并添加數(shù)據(jù)提交的方法,具體代碼如下所示表單提交控制器恒宇少年碼云裝載參數(shù)測(cè)試教師名稱, 在國(guó)內(nèi)企業(yè)開(kāi)發(fā)項(xiàng)目中大多數(shù)都已經(jīng)偏向Spring家族式的開(kāi)發(fā)風(fēng)格,在前幾年國(guó)內(nèi)項(xiàng)目都是以Structs2作為Web開(kāi)發(fā)的主導(dǎo),不過(guò)由于近幾年發(fā)生的事情確實(shí)讓開(kāi)發(fā)者對(duì)它失去了以往的信心。與此同時(shí)Spring家族發(fā)布...

    Ali_ 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<