日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring MVC控制器的单元测试:配置

發(fā)布時(shí)間:2023/12/3 javascript 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC控制器的单元测试:配置 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

傳統(tǒng)上,為Spring MVC控制器編寫(xiě)單元測(cè)試既簡(jiǎn)單又成問(wèn)題。 盡管編寫(xiě)調(diào)用控制器方法的單元測(cè)試非常簡(jiǎn)單,但問(wèn)題是這些單元測(cè)試不夠全面。 例如,我們不能僅通過(guò)調(diào)用已測(cè)試的控制器方法來(lái)測(cè)試控制器映射,驗(yàn)證和異常處理。

Spring MVC Test通過(guò)使我們能夠通過(guò)DispatcherServlet調(diào)用控制器方法來(lái)解決了這個(gè)問(wèn)題。 這是本教程的第一部分,描述了Spring MVC控制器的單元測(cè)試,并描述了如何配置單元測(cè)試。 讓我們開(kāi)始吧。

使用Maven獲取所需的依賴關(guān)系

我們可以通過(guò)在pom.xml文件中聲明以下測(cè)試依賴項(xiàng)來(lái)獲取所需的依賴項(xiàng):

  • JUnit 4.11
  • Mockito Core 1.9.5
  • Spring測(cè)試3.2.3發(fā)布

pom.xml文件的相關(guān)部分如下所示:

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope> </dependency> <dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>1.9.5</version><scope>test</scope> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>3.2.3.RELEASE</version><scope>test</scope> </dependency>

讓我們繼續(xù)前進(jìn),快速看一下示例應(yīng)用程序。

我們的示例應(yīng)用程序剖析

本教程的示例應(yīng)用程序?yàn)榇k事項(xiàng)提供CRUD操作。 為了了解測(cè)試類(lèi)的配置,我們必須對(duì)測(cè)試的控制器類(lèi)有一些了解。

在這一點(diǎn)上,我們需要知道以下問(wèn)題的答案:

  • 它有什么依賴性?
  • 如何實(shí)例化?

通過(guò)查看TodoController類(lèi)的源代碼,我們可以獲得這些問(wèn)題的答案。 TodoController類(lèi)的相關(guān)部分如下所示:

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.stereotype.Controller;@Controller public class TodoController {private final TodoService service;private final MessageSource messageSource;@Autowiredpublic TodoController(MessageSource messageSource, TodoService service) {this.messageSource = messageSource;this.service = service;}//Other methods are omitted. }

如我們所見(jiàn),控制器類(lèi)具有兩個(gè)依賴項(xiàng): TodoService和MessageSource 。 另外,我們可以看到我們的控制器類(lèi)使用構(gòu)造函數(shù)注入。

至此,這就是我們需要的所有信息。 接下來(lái),我們將討論我們的應(yīng)用程序上下文配置。

配置應(yīng)用程序上下文

為我們的應(yīng)用程序和測(cè)試維護(hù)單獨(dú)的應(yīng)用程序上下文配置很麻煩。 同樣,如果我們?cè)趹?yīng)用程序的應(yīng)用程序上下文配置中進(jìn)行了某些更改,但是忘記對(duì)測(cè)試上下文進(jìn)行相同的更改,則會(huì)導(dǎo)致問(wèn)題。

這就是為什么對(duì)示例應(yīng)用程序的應(yīng)用程序上下文配置進(jìn)行劃分的原因,我們可以在測(cè)試中重用部分應(yīng)用程序。

我們的應(yīng)用程序上下文配置劃分如下:

  • 第一個(gè)應(yīng)用程序配置類(lèi)稱為ExampleApplicationContext ,它是我們應(yīng)用程序的“主要”配置類(lèi)。
  • 第二個(gè)配置類(lèi)負(fù)責(zé)配置應(yīng)用程序的Web層。 此類(lèi)的名稱是WebAppContext ,它是我們?cè)跍y(cè)試中將使用的配置類(lèi)。
  • 第三個(gè)配置類(lèi)稱為PersistenceContext ,它包含應(yīng)用程序的持久性配置。

注意:示例應(yīng)用程序還具有使用XML配置文件的有效應(yīng)用程序上下文配置。 與Java配置類(lèi)相對(duì)應(yīng)的XML配置文件為: exampleApplicationContext.xml ,exampleApplicationContext-web.xml和exampleApplicationContext-persistence.xml 。

讓我們看一下Web層的應(yīng)用程序上下文配置,并了解如何配置測(cè)試上下文。

配置Web層

Web層的應(yīng)用程序上下文配置具有以下職責(zé):

  • 它啟用了注釋驅(qū)動(dòng)的Spring MVC。
  • 它配置靜態(tài)資源(例如CSS文件和Javascript文件)的位置。
  • 它確保靜態(tài)資源由容器的默認(rèn)Servlet提供。
  • 它確保在組件掃描期間找到控制器類(lèi)。
  • 它配置ExceptionResolver bean。
  • 它配置ViewResolver bean。
  • 讓我們繼續(xù)看一下Java配置類(lèi)和XML配置文件。

    Java配置

    如果使用Java配置,則WebAppContext類(lèi)的源代碼如下所示:

    import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView;import java.util.Properties;@Configuration @EnableWebMvc @ComponentScan(basePackages = {"net.petrikainulainen.spring.testmvc.common.controller","net.petrikainulainen.spring.testmvc.todo.controller" }) public class WebAppContext extends WebMvcConfigurerAdapter {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("/static/");}@Overridepublic void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();}@Beanpublic SimpleMappingExceptionResolver exceptionResolver() {SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();Properties exceptionMappings = new Properties();exceptionMappings. put("net.petrikainulainen.spring.testmvc.todo.exception.TodoNotFoundException", "error/404");exceptionMappings.put("java.lang.Exception", "error/error");exceptionMappings.put("java.lang.RuntimeException", "error/error");exceptionResolver.setExceptionMappings(exceptionMappings);Properties statusCodes = new Properties();statusCodes.put("error/404", "404");statusCodes.put("error/error", "500");exceptionResolver.setStatusCodes(statusCodes);return exceptionResolver;}@Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();viewResolver.setViewClass(JstlView.class);viewResolver.setPrefix("/WEB-INF/jsp/");viewResolver.setSuffix(".jsp");return viewResolver;} }

    XML配置

    如果使用XML配置, exampleApplicationContext-web.xml文件的內(nèi)容如下所示:

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"><mvc:annotation-driven/><mvc:resources mapping="/static/**" location="/static/"/><mvc:default-servlet-handler/><context:component-scan base-package="net.petrikainulainen.spring.testmvc.common.controller"/><context:component-scan base-package="net.petrikainulainen.spring.testmvc.todo.controller"/><bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><prop key="net.petrikainulainen.spring.testmvc.todo.exception.TodoNotFoundException">error/404</prop><prop key="java.lang.Exception">error/error</prop><prop key="java.lang.RuntimeException">error/error</prop></props></property><property name="statusCodes"><props><prop key="error/404">404</prop><prop key="error/error">500</prop></props></property></bean><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/><property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/></bean> </beans>

    配置測(cè)試上下文

    我們的測(cè)試上下文的配置有兩個(gè)職責(zé):

  • 它配置一個(gè)MessageSource bean,供我們的控制器類(lèi)(反饋消息)和Spring MVC(驗(yàn)證錯(cuò)誤消息)使用。 我們之所以需要這樣做,是因?yàn)镸essageSource bean是在應(yīng)用程序上下文配置的“主”配置類(lèi)(或文件)中配置的。
  • 它創(chuàng)建一個(gè)TodoService模擬,該模擬被注入到我們的控制器類(lèi)中。
  • 讓我們了解如何使用Java配置類(lèi)和XML配置文件配置測(cè)試上下文。

    Java配置

    如果我們通過(guò)使用Java配置來(lái)配置測(cè)試上下文,則TestContext類(lèi)的源代碼如下所示:

    import org.mockito.Mockito; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource;@Configuration public class TestContext {@Beanpublic MessageSource messageSource() {ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();messageSource.setBasename("i18n/messages");messageSource.setUseCodeAsDefaultMessage(true);return messageSource;}@Beanpublic TodoService todoService() {return Mockito.mock(TodoService.class);} }

    XML配置

    如果我們使用XML配置來(lái)配置測(cè)試上下文,那么testContext.xml文件的內(nèi)容如下所示:

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"><property name="basename" value="i18n/messages"/><property name="useCodeAsDefaultMessage" value="true"/></bean><bean id="todoService" name="todoService" class="org.mockito.Mockito" factory-method="mock"><constructor-arg value="net.petrikainulainen.spring.testmvc.todo.service.TodoService"/></bean> </beans>

    配置測(cè)試類(lèi)別

    我們可以使用以下選項(xiàng)之一配置測(cè)試類(lèi):

  • Standalone配置允許我們注冊(cè)一個(gè)或多個(gè)控制器(使用@Controller注釋注釋的類(lèi))并以編程方式配置Spring MVC基礎(chǔ)結(jié)構(gòu)。 如果我們的Spring MVC配置簡(jiǎn)單明了,那么這種方法是可行的選擇。
  • 基于WebApplicationContext的配置允許我們使用完全初始化的WebApplicationContext來(lái)配置Spring MVC基礎(chǔ)結(jié)構(gòu)。 如果我們的Spring MVC配置太復(fù)雜以至于使用獨(dú)立配置沒(méi)有任何意義,那么這種方法會(huì)更好。
  • 讓我們繼續(xù)前進(jìn),找出如何使用這兩個(gè)配置選項(xiàng)來(lái)配置測(cè)試類(lèi)。

    使用獨(dú)立配置

    我們可以按照以下步驟配置測(cè)試類(lèi):

  • 使用@RunWith注釋為類(lèi)添加注釋,并確保使用MockitoJUnitRunner執(zhí)行測(cè)試。
  • 將MockMvc字段添加到測(cè)試類(lèi)。
  • 將TodoService字段添加到測(cè)試類(lèi),并使用@Mock注釋對(duì)字段進(jìn)行注釋。 此注釋將字段標(biāo)記為模擬。 該字段由MockitoJUnitRunner初始化。
  • 向該類(lèi)添加一個(gè)私有的exceptionResolver()方法。 此方法創(chuàng)建一個(gè)新的SimpleMappingExceptionResolver對(duì)象,對(duì)其進(jìn)行配置,然后返回創(chuàng)建的對(duì)象。
  • 將私有messageSource()方法添加到該類(lèi)。 此方法創(chuàng)建一個(gè)新的ResourceBundleMessageSource對(duì)象,對(duì)其進(jìn)行配置,然后返回創(chuàng)建的對(duì)象。
  • 向該類(lèi)添加一個(gè)私有的validator()方法。 此方法創(chuàng)建一個(gè)新的LocalValidatorFactoryBean對(duì)象并返回創(chuàng)建的對(duì)象。
  • 向該類(lèi)添加一個(gè)專用的viewResolver()方法。 此方法創(chuàng)建一個(gè)新的InternalResourceViewResolver對(duì)象,對(duì)其進(jìn)行配置,然后返回創(chuàng)建的對(duì)象。
  • 將setUp()方法添加到測(cè)試類(lèi),并使用@Before注釋對(duì)方法進(jìn)行注釋。 這樣可以確保在每次測(cè)試之前都調(diào)用該方法。 該方法通過(guò)調(diào)用MockMvcBuilders類(lèi)的standaloneSetup()方法創(chuàng)建一個(gè)新的MockMvc對(duì)象,并以編程方式配置Spring MVC基礎(chǔ)結(jié)構(gòu)。
  • 我們的測(cè)試類(lèi)的源代碼如下所示:

    import org.junit.Before; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.context.MessageSource; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView;import java.util.Properties;@RunWith(MockitoJUnitRunner.class) public class StandaloneTodoControllerTest {private MockMvc mockMvc;@Mockprivate TodoService todoServiceMock;@Beforepublic void setUp() {mockMvc = MockMvcBuilders.standaloneSetup(new TodoController(messageSource(), todoServiceMock)).setHandlerExceptionResolvers(exceptionResolver()).setValidator(validator()).setViewResolvers(viewResolver()).build();}private HandlerExceptionResolver exceptionResolver() {SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();Properties exceptionMappings = new Properties();exceptionMappings. put("net.petrikainulainen.spring.testmvc.todo.exception.TodoNotFoundException", "error/404");exceptionMappings.put("java.lang.Exception", "error/error");exceptionMappings.put("java.lang.RuntimeException", "error/error");exceptionResolver.setExceptionMappings(exceptionMappings);Properties statusCodes = new Properties();statusCodes.put("error/404", "404");statusCodes.put("error/error", "500");exceptionResolver.setStatusCodes(statusCodes);return exceptionResolver;}private MessageSource messageSource() {ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();messageSource.setBasename("i18n/messages");messageSource.setUseCodeAsDefaultMessage(true);return messageSource;}private LocalValidatorFactoryBean validator() {return new LocalValidatorFactoryBean();}private ViewResolver viewResolver() {InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();viewResolver.setViewClass(JstlView.class);viewResolver.setPrefix("/WEB-INF/jsp/");viewResolver.setSuffix(".jsp");return viewResolver;} }

    使用獨(dú)立配置有兩個(gè)問(wèn)題:

  • 即使我們的Spring MVC配置非常簡(jiǎn)單,我們的測(cè)試類(lèi)看起來(lái)還是一團(tuán)糟。 當(dāng)然,我們可以通過(guò)將Spring MVC基礎(chǔ)結(jié)構(gòu)組件的創(chuàng)建移到一個(gè)單獨(dú)的類(lèi)中來(lái)清理它。 這留給讀者練習(xí)。
  • 我們必須復(fù)制Spring MVC基礎(chǔ)結(jié)構(gòu)組件的配置。 這意味著,如果我們更改應(yīng)用程序的應(yīng)用程序上下文配置中的某些內(nèi)容,則必須記住也要對(duì)測(cè)試進(jìn)行相同的更改。
  • 使用基于WebApplicationContext的配置

    我們可以按照以下步驟配置測(cè)試類(lèi):

  • 使用@RunWith注釋對(duì)測(cè)試類(lèi)進(jìn)行注釋,并確保通過(guò)使用SpringJUnit4ClassRunner執(zhí)行測(cè)試。
  • 用@ContextConfiguration注釋為該類(lèi)添加注釋,并確保使用正確的配置類(lèi)(或XML配置文件)。 如果要使用Java配置,則必須將配置類(lèi)設(shè)置為classes屬性的值。 另一方面,如果我們更喜歡XML配置,則必須將配置文件設(shè)置為locations屬性的值。
  • 用@WebAppConfiguration批注對(duì)類(lèi)進(jìn)行批注。 此批注確保為我們的測(cè)試加載的應(yīng)用程序上下文是WebApplicationContext 。
  • 將MockMvc字段添加到測(cè)試類(lèi)。
  • 將TodoService字段添加到測(cè)試類(lèi),并使用@Autowired批注對(duì)該字段進(jìn)行批注。
  • 將WebApplicationContext字段添加到測(cè)試類(lèi),并使用@Autowired批注對(duì)該字段進(jìn)行批注。
  • 將setUp()方法添加到測(cè)試類(lèi),并使用@Before注釋對(duì)方法進(jìn)行注釋。 這樣可以確保在每次測(cè)試之前都調(diào)用該方法。 此方法負(fù)責(zé):在每次測(cè)試之前重置服務(wù)模擬,并通過(guò)調(diào)用MockMvcBuilders類(lèi)的webAppContextSetup()方法來(lái)創(chuàng)建新的MockMvc對(duì)象。
  • 我們的測(cè)試類(lèi)的源代碼如下所示:

    import org.junit.Before; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {TestContext.class, WebAppContext.class}) //@ContextConfiguration(locations = {"classpath:testContext.xml", "classpath:exampleApplicationContext-web.xml"}) @WebAppConfiguration public class WebApplicationContextTodoControllerTest {private MockMvc mockMvc;@Autowiredprivate TodoService todoServiceMock;@Autowiredprivate WebApplicationContext webApplicationContext;@Beforepublic void setUp() {//We have to reset our mock between tests because the mock objects//are managed by the Spring container. If we would not reset them,//stubbing and verified behavior would "leak" from one test to another.Mockito.reset(todoServiceMock);mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();} }

    我們的測(cè)試類(lèi)的配置看起來(lái)比使用獨(dú)立配置的配置干凈得多。 但是,“缺點(diǎn)”是我們的測(cè)試使用了完整的Spring MVC基礎(chǔ)架構(gòu)。 如果我們的測(cè)試類(lèi)僅實(shí)際使用一些組件,則這可能是過(guò)大的殺傷力。

    摘要

    現(xiàn)在,我們已經(jīng)使用獨(dú)立安裝程序和基于WebApplicationContext的安裝程序配置了單元測(cè)試類(lèi)。 這篇博客文章教會(huì)了我們兩件事:

    • 我們了解到,劃分應(yīng)用程序上下文配置很重要,這樣我們才能在測(cè)試中重用部分內(nèi)容。
    • 我們了解了獨(dú)立配置和基于WebApplicationContext的配置之間的區(qū)別。

    本教程的下一部分描述了如何為“常規(guī)” Spring MVC控制器編寫(xiě)單元測(cè)試。

    PS此博客文章的示例應(yīng)用程序可在Github上獲得 。

    參考: Spring MVC控制器的單元測(cè)試: Petri Kainulainen博客上來(lái)自我們JCG合作伙伴 Petri Kainulainen的配置 。

    翻譯自: https://www.javacodegeeks.com/2013/07/unit-testing-of-spring-mvc-controllers-configuration-2.html

    總結(jié)

    以上是生活随笔為你收集整理的Spring MVC控制器的单元测试:配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。