如何使用Java單元測試助手高效構建和改進Spring測試?

Spring框架(連同Spring Boot一塊兒)是最流行的Java企業軟件框架之一。它在關鍵任務應用中的使用意味着它的質量和安全性受到了嚴格的審查。html

此前,咱們討論了開發人員如何不喜歡單元測試,儘管它的改進記錄已被證明,並詳細介紹了Parasoft Jtest的單元測試助手如何提供一種指導性和自動化的測試方法,使測試不只更容易接受,並且更容易和更有效。在這篇文章中,我將繼續以Spring框架爲主題,向你展現如何在這個重要的應用框架中利用自動化和引導式測試。java

測試Spring應用的挑戰

Spring框架爲集成測試提供了不錯的支持,但要正確設置測試用例,須要大量的手工編碼。構建和維護Spring應用的測試給開發人員帶來了一系列獨特的挑戰,包括如下幾點安全

  • 必須對Spring框架進行初始化和配置
  • 應用程序一般有第三方庫的依賴性(持久存儲、外部服務等)
  • 應用程序一般使用內置的Spring功能,用於會話、安全、消息傳遞等。對於剛接觸Spring測試的開發人員來講,這些功能的設置可能會很棘手
  • 須要適當配置應用程序的依賴關係(即Bean

這些挑戰,再加上編寫全面的可維護的測試套件通常須要花費大量的時間,致使開發人員沒有編寫足夠的測試,反過來,這又會致使安全漏洞、缺陷、迴歸和許多使人頭痛的問題。app

Parasoft Jtest Unit Test Assistant能夠幫助你,它使生成、改進和維護JUnit測試的過程變得更加簡單和省時,這樣開發人員就能夠快速構建好的測試,並回到他們更加偏好的事情上——編寫代碼。框架

Spring MVC測試框架

Spring框架包括一個測試框架,它使控制器、服務和其餘組件的測試變得更加容易。它包括配置Spring測試容器、調用Controller處理方法和使用自定義斷言驗證行爲的功能。函數

一個Spring MVC控制器的例子工具

@Controller

public class TodoController {     @Autowired

    private TodoService service;

    @GetMapping("/")    public String findAll(Model model) {

        List<Todo> todos = service.findAll();

        model.addAttribute("todos", todos);

        return "todo/list";

    }

}

  

這個示例中,控制器實現了一個簡單的REST服務,以從 "待辦事項 "列表中獲取項目。它依賴於一個TodoService,其中包含業務邏輯。單元測試

爲了測試findAll方法,咱們須要一個JUnit測試,它能夠完成如下工做測試

  • Spring容器中配置被測試的ControllerTodoController所依賴的TodoService
  • findAll處理方法發送一個有效的請求。
  • 驗證響應的元素,包括返回值("todo/list")和Model屬性 "todos"

一個Spring MVC Junit測試的例子多是這樣的ui

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration

public class TodoControllerTest {

    @Autowired

    TodoController controller;

 

    @Autowired

    TodoService todoService;

 

    MockMvc mockMvc;

 

    @Before

    public void setup() {

        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();

    }

 

    @Configuration

    static class Config {

        @Bean

        public TodoController getTodoController() {

            return new TodoController();

        }

 

        @Bean

        public TodoService getTodoService() {

            return new TodoService();

        }

    }

 

    @Test

    public void testFindAll() throws Exception {

        mockMvc.perform(get("/")).andExpect(view().name("todo/list"));

    }

}

  

上面的例子是一個很是簡單的測試——但仍是有不少「樣板」代碼要寫,有不少事情要作。在這個例子中,咱們使用一個內部的Configuration類爲Spring配置了一個控制器和它的服務,而後使用MockMvc函數向處理程序發送請求。而後,咱們使用MockMvc函數向處理者方法發送請求(使用perform),並使用andExpect驗證返回的視圖名稱。

上面的測試有什麼問題嗎?其實沒什麼——但想象一下一個更復雜的控制器方法,有多個處理方法,接受更多的參數併產生更多的輸出。編寫測試會花費更多的時間,特別是若是良好的測試覆蓋率很重要的話。此外,大多數真實的測試須要更多的配置(XML或類配置、會話和環境、安全等)。

使用Parasoft Jtest生成Spring測試

Parasoft Jtest的單元測試助手能夠幫助開發人員以多種方式編寫Spring測試

  1. 自動快速生成Spring MVC測試的模板代碼
  2. 自動生成參數化測試,提升測試覆蓋率
  3. 模擬依賴關係,以隔離輔助方法並簡化測試
  4. 在運行時收集覆蓋率數據並分析測試流程
  5. 爲改進測試提供建議,並提供快速修補辦法

自動生成測試

Parasoft Jtest中生成Spring測試是很直接的——只需在你的IDE中爲你的控制器選擇一個Spring處理方法,並選擇一個測試建立動做

選擇Regular SpringParameterized Spring會自動爲你生成模板化的Spring MVC測試,包括Configuration類(以及你的控制器所依賴的全部Bean)。mockMvc.perform調用也被添加進來,並被預先配置爲調用建立測試的處理方法。Jtest 單元測試助手甚至增長了一些例子斷言,你能夠取消註釋和配置。

Parasoft Jtest支持使用XML或類配置生成測試,經過在偏好設置中設置 "ContextConfiguration attributes for Spring tests "選項。

模擬依賴性

在單元測試中管理依賴關係是相當重要的,由於大部分的複雜性和工做來自於隔離被測單元。Jtest單元測試助手默認使用MockitoPowerMockito來模擬依賴關係(若是你不但願這樣,能夠在偏好設置中禁用)。模擬依賴關係容許測試控制這些依賴關係,將處理程序方法與應用程序的其餘部分隔離開來,以便將測試工做集中在處理程序上。在咱們的示例處理程序中,findAll方法是在TodoService上被調用的——若是咱們使用一個真正的TodoService,咱們就有效地測試了TodoControllerTodoService。這多是咱們在集成測試中想要的,但不是在單元測試中想要的。在測試中模擬TodoService.findAll的響應,可讓咱們把測試工做集中在處理方法上。

若是你想了解更多關於在Spring測試中模擬依賴關係的信息,請閱讀個人下一篇文章。)

Spring Boot

因爲Spring BootBean提供了簡化的配置,以及額外的測試註釋,因此當單元測試助理在的項目中檢測到Spring Boot時,會生成略有不一樣的測試。例如,MockMvc是自動鏈接的,依賴關係使用@MockBean進行模擬,並使用@SpringBootTest註解。

運行測試和分析結果

你可使用任何普通的JUnit運行器運行生成的測試。Parasoft Jtest提供了運行JUnit和分析測試的工具欄操做。

測試運行後,會顯示測試執行流程,單元測試助手會提出改進測試的建議,並在IDE中報告

提供處理程序方法輸入

處理程序方法一般被配置爲接受路徑、查詢或其餘參數做爲方法的參數。要測試MVC處理程序方法,可使用MockMvc來構建路徑/查詢和調用該方法所需的任何其餘參數。

Jtest單元測試助理會自動配置mockMvc.perform調用來調用處理程序方法。單個參數在測試中顯示爲局部變量(或參數化測試中的參數),須要配置這些參數才能使測試正確運行。

例如(下文單元測試助手縮寫爲UTA

@Test public void testGetPerson() throws Throwable {     // When     String id = ""; // UTA: Configure an appropriate parameter value since the tested method depends on it     ResultActions actions = mockMvc.perform(get("/people/" + id));

  

這裏,須要配置 "id"字符串——若是沒有,那麼使用的路徑將是"/people/"Spring將不會把提供的路徑匹配到合適的處理方法。

class="p1>單元測試助手會尋找各類類型的處理程序方法參數,並經過如下方式自動爲它們準備測試

  • HttpSession(增長一個setAttribute()調用的例子)
  • 頭部(增長一個header()調用)
  • 請求主體(添加一個payload變量和content()調用)
  • 認證(在setup方法中添加了一個實例,以及一個principal()調用)

運行一個不會致使處理程序方法被調用的測試,會產生相似下面的建議:

驗證處理程序方法的輸出

根據處理程序方法要提供給調用者的內容,它可能返回多種類型。大多數狀況下,處理方法會返回一個ModelAndView(或相似的對象,如ModelRedirectView)來爲頁面提供服務,或者返回某種類型的ResponseEntity(有時只是要序列化的原始對象)。這個響應能夠訪問Spring MVC測試框架進行驗證。

例如,Jtest單元測試助理爲一個返回ModelAndView的處理方法添加了如下斷言

  // When

  String id = "1";

  ResultActions actions = mockMvc.perform(get("/people/" + id));

 

  // Then

  // actions.andExpect(status().isOk());

  // actions.andExpect(header().string("", ""));

  // actions.andExpect(view().name(""));

  // actions.andExpect(model().attribute("", ""));

  

一旦測試生成,你就能夠取消對這些斷言的註釋並填充值,以快速創建一個有用的和有價值的測試。若是一個斷言在運行時失敗了,單元測試助手提供了一個建議和快速修復,以自動更新預期值或簡單地刪除斷言。爲了快速設置一個正確的斷言值,你能夠取消對斷言的註釋,讓它失敗,而後使用快速修復來設置正確的指望值。

總結

Spring(結合Spring Boot)是領先的企業級Java應用框架,所以須要適當的測試水平,以確保用它構建的應用的質量和安全性。但遺憾的是,這種水平的測試目前尚未實現,主要是因爲缺少時間和須要大量的人工編碼和維護。Parasoft Jtest 單元測試助手不只提供了單元測試自動化,還提供了指導性的測試建立和依賴性管理,以加速測試建立和減小維護。

要了解更多信息,請閱讀單元測試助手如何利用模擬框架幫助進行依賴性管理

相關文章
相關標籤/搜索