1. 程式人生 > >基於Spring MVC做單元測試 —— 使用JMockit

基於Spring MVC做單元測試 —— 使用JMockit

轉載地址:http://www.techv5.com/topic/696/

下面再介紹一下通過JMockit這個Java Mock工具來進行spring的單元測試,其特點是不需指定spring的配置檔案,任何物件都可以mock出來並進行關聯。

Controller

import com.odde.mail.model.Result;
import com.odde.mail.service.MailService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.map.ObjectMapper
; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import static java.lang.String.format; @Controller @RequestMapping("/mail") public class MailController { private static final Log log = LogFactory.getLog(MailController.class); private final ObjectMapper mapper = new ObjectMapper
(); @Autowired private MailService mailService; @RequestMapping(value = "/send", method = RequestMethod.POST, produces = "text/plain;charset=UTF-8") public @ResponseBody String send(@RequestParam("recipients") String recipients, @RequestParam("subject") String subject, @RequestParam("content") String content) throws Exception { log.debug("mail controller send start"); log.debug(format("recipients:%s", recipients)); log.debug(format("subject:%s", subject)); log.debug(format("content:%s", content)); Result mailResult = mailService.send(recipients, subject, content); String result = mapper.writeValueAsString(mailResult); log.debug(format("result:%s", result)); log.debug("mail controller send finish"); return result; } }

首先我們還是來看一下使用了JMockit的Controller單元測試是怎麼寫的,Controller的功能程式碼可見上面。

import com.odde.mail.model.Result;
import com.odde.mail.service.MailService;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Tested;
import mockit.integration.junit4.JMockit;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

@RunWith(JMockit.class)
public class MailControllerTest {
    @Tested
    MailController mailController;

    @Injectable
    private MailService mailService;

    @Test
    public void should_return_status_success_when_send_mail_success() throws Exception {
        new Expectations() { {
            mailService.send("[email protected]", "test", "test");
            result = new Result("成功");
        } };

        String result = mailController.send("[email protected]", "test", "test");

        assertThat(result, is("{\"status\":\"成功\"}"));
    }
}
  • @RunWith(JMockit.class): 指定單元測試的執行類為JMockit.class;
  • @Tested: 這個Annotate是指被測試類,在這個測試案例中我們要測試的是MailController,所以我們給其打上這個標籤;
  • @Injectable: 這個Annotate可以將物件進行mock並自動關聯到被測試類,而不需要通過其他檔案類似spring的配置檔案等來進行關聯;
  • @Expectations: mock物件mailService的send方法,讓其返回一個Result物件;

Service

再來看一下Service的單元測試要怎麼改寫,同樣Service的功能程式碼可以看上一篇Post。

import com.odde.mail.model.Recipient;
import com.odde.mail.model.Result;
import com.odde.mail.repo.RecipientRepository;
import mockit.Injectable;
import mockit.NonStrictExpectations;
import mockit.Tested;
import mockit.integration.junit4.JMockit;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.List;

import static java.util.Arrays.asList;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

@RunWith(JMockit.class)
public class RecipientServiceTest {

    @Tested
    private RecipientService recipientService;

    @Injectable
    private RecipientRepository recipientRepository;

    @Test
    public void should_return_success_when_add_recipient_not_exist() throws Exception {
        Result result = recipientService.add("Tom", "[email protected]");
        assertThat(result.getStatus(), is("成功"));
    }
}

相對Controller Test這裡少了一步對recipientRepository物件findByEmail方法的mock,因為如果不通過Expectations進行方法mock的話,方法會預設返回null,而我們要測試的場景正是需要findByEmail方法返回null,所以mock方法這一步我們也省了。改寫後的整體程式碼也比原來的少了很多,而且速度更快。

適當使用Mock框架

JMockit功能非常強大,不僅可以輕鬆處理上面的這些測試場景,還可以對static,final,private等方法進行mock,可以讓你的單元測試毫無阻礙的進行。

但是如果過度的使用Mock框架,會讓功能程式碼的壞味道被掩蓋。本來單元測試的設計可以讓你發現功能程式碼上的一些設計是否合理,比如有沒有緊耦合等,但使用JMockit可以讓你在設計不合理的程式碼上也可以輕鬆地進行單元測試,這樣你就很難發現功能程式碼上的問題了。

所以建議JMockit等類似的mock框架還是要謹慎使用,首先要保證功能程式碼設計合理,滿足面向物件設計的要求,再來考慮提高單元測試效率的問題。

相關推薦

基於Spring MVC單元測試 —— 使用JMockit

轉載地址:http://www.techv5.com/topic/696/ 下面再介紹一下通過JMockit這個Java Mock工具來進行spring的單元測試,其特點是不需指定spring的配置檔案,任何物件都可以mock出來並進行關聯。 Controller im

基於spring與mockito單元測試Mock對象註入

err else archive ali spro 反射 lse ica sce 轉載:http://www.blogjava.net/qileilove/archive/2014/03/07/410713.html 1.關鍵詞   單元測試、spring、mockito

Spring Mvc controller單元測試

 弄了一下午的controller測試類,(主要還是不理解)~~~~~ 現在把我測試通過的步驟儲存下來,為需要的人一份借鑑 SpringMVC controller測試較簡單,從功能角度劃分,可分為兩種。一種是呼叫請求路徑測試,另一種是直接呼叫Controller方法測試

Spring mvc Junit單元測試異常解決

今天在做單元測試的時候出現了各種異常情況。可是專案通過Tomcat容器釋出執行沒有任何問題,專案框架是spring 4.3.3 + mybatis。問題一:Caused by: org.springframework.beans.factory.BeanCreationExc

基於Spring MVC(REST API)單元測試(mockito)

最近在公司用的Spring Mvc REST API框架做了一個專案,並且做了基於Spring的單元測試,今天先講一下基於Spring框架的單元測試,測試使用的是Spring自帶的test元件,再結合Mockito一起編寫測試案例,以下示例會包括Controller和Ser

Spring容器中的類單元測試

SpringBoot測試步驟 直接在測試類上面加上如下2個註解 @RunWith(SpringRunner.class) @SpringBootTest 就能取到spring中的容器的例項,如果配置了@Autowired那麼就自動將物件注入 在測試環境中獲取一個bea

JUnit4結合spring單元測試

做單元測試非常簡單,結合spring做單元測試也很簡單。 首先,導包 先看一下目錄結構: 下面是測試基類(): package pms_test; import org.junit.Test; import org.junit.runner.RunWith; im

基於mock物件和JUnit框架簡化Spring Web元件單元測試

對於Java元件開發者來說,他們都盼望擁有一組能夠對元件開發提供全面測試功能的好用的單元測試。一直以來,與測試獨立的Java物件相比,測試傳統型J2EE Web元件是一項更為困難的任務,因為Web元件必須執行在某種伺服器平臺上並且它們還要與基於HTTP的Web互動細節相聯

spring中用MockMvc單元測試

轉自  http://blog.csdn.net/pengoneeast/article/details/46890581 一般測試驅動開發專案中,我們會在Maven中建立一個專案檔案和一個一一對應的測試專案檔案。每寫好一個模組,先對其進行單元測試,再整合到現有的系統

單元測試系列三-基於Springboot+Junit+Mockito單元測試

前言 前面的兩篇文章討論過《為什麼要寫單元測試,何時寫,寫多細》和《單元測試規範》,這篇文章介紹如何使用Springboot+Junit+Mockito做單元測試,案例選取撮合交易的一個類來做單元測試。 單元測試前先理解需求 要寫出好的單測,必須先理解

Spring中如何使用Mockito單元測試

在Spring環境下做單元測試常常遇到很多問題,Controller層還好說,Spring本身提供了很多方法來支援,這個可以看我的另一篇文章 但是在服務層和持久層,如果是使用註解注入的方式來設計的

Spring Boot的單元測試(Unit Test)

java spring boot unit test 最近做了一些Spring Boot單元測試方面的東西,總結一下。單元測試盡量要和Spring Boot框架減少耦合度,當你在測試某一項功能點是需要mock太多的對象時你就應該意識到這個功能點的耦合度太高了使用Constructor Inject

MVC單元測試實踐之健身網站(一)-項目概述

dto 使用 基礎 資料 ima size 描述 健身 nunit 前不久剛剛通過租房網站的開發學習了MVC,並隨後學習了單元測試相關的基礎,現在開始健身網站的開發,該項目將結合MVC與單元測試,在開發實踐過程中,趁熱打鐵,鞏固並運用之前的內容。 一 健身網站功能描述

MVC單元測試實踐之健身網站(六)-計劃的添加與重置

兼容 跳轉 需要 以及 str 額外 休息 保存 bsp 健身計劃需要使用者自己定制,沒有現成的內容可供選擇。本篇就是關於健身計劃的添加與重置功能的一部分。 一 功能描述 a) 關於計劃的定制,決定以周期的方式,比如有人會以一周為周期,然後安排每周的1、3、5進行鍛煉。系統

MVC單元測試實踐之健身網站(七)-添加計劃

感覺 同步 語句 -s mil none tro c# 技術分享 ?計劃的制定涉及到周期-動作包-動作的關聯操作,在上一篇<計劃的添加與重置>完成了周期的設置、動作包的添加,現在要完成的是動作的添加操作。 一 具體功能 a) 在選定了一個大周期具有的天數後,

Spring整合activiti單元測試

context ons col unit test junit config har 配置 1 ** 2 * Spring測試activiti配置是否正常 3 * <p>Title: SpringActivitiTest</p>

MVC單元測試實踐之健身網站(完)-備案與部署

網站 img 指標 身體 根據 直觀 健身 自己的 tts 主頁-http://www.zhixin9001.cn/Home/Introduce GitHub- https://github.com/zhixin9001/Fitness 這是關於Fit網站的最後一篇,這

Spring-test + Junit4單元測試

編碼 繼承 tco 試用 ont 操作 主鍵 app nbsp 一、僅使用Junit進行單元測試不足之處: 1、導致多次Spring容器初始化問題    —>根據JUnit測試方法的調用流程,每執行一個測試方法都會創建一個測試用例的實例並調用setUp()方法。由於一

python + unittest 單元測試之學習筆記

stl unittest 例子 gin pre log script 有關 assert 單元測試在保證開發效率、可維護性和軟件質量等方面有很重要的地位,所謂的單元測試,就是對一個類,一個模塊或者一個函數進行正確性檢測的一種測試方式。 這裏主要是就應用 python + u

Junit工具單元測試

Junit 單元測試eclipse 創建Junit單元測試之後,提示: 問題原因:沒有導入Junit的 library解決方法: 在項目上點擊右鍵--->Properties--->Java Build Path--->(Libraries標簽)add Library-->JUnit4