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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring MVC测试框架入门–第2部分

發布時間:2023/12/3 javascript 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC测试框架入门–第2部分 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這個迷你系列的第一個博客介紹了Spring MVC測試框架,并展示了其在單元測試Spring MVC Controller類中作為控制器而不是POJO進行單元測試的用途。 現在是時候討論使用框架進行集成測試了。

“集成測試”是指將Spring上下文加載到測試環境中,以便控制器可以在“端到端”測試中與合作者一起工作。

同樣,我將從Spring Social Facebook項目中為FacebookPostsController編寫一個測試,并且正如您所期望的那樣,該測試將是我的FacebookPostsControllerTest類的集成測試版本。 如果需要查看FacebookPostsController代碼或原始的FacebookPostsControllerTest代碼,請查看我的上一個博客 。 有關FacebookPostsController代碼的完整介紹,請參見Spring Social Facebook博客 。

創建集成測試的第一步是將Spring上下文加載到測試環境中。 這是通過在FacebookPostsControllerTest類中添加以下注釋來完成的:

  • @RunWith ( SpringJUnit4ClassRunner.class )
  • @WebAppConfiguration
  • @ContextConfiguration(“文件名”)
  • @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration({ "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml", "file:src/main/webapp/WEB-INF/spring/data.xml" }) public class FacebookPostsControllerTest {

    @RunWith ( SpringJUnit4ClassRunner.class )或@ContextConfiguration(“ file-names”)并沒有什么新意,因為它們從Spring 2.5開始就出現了,如果您是Spring開發人員,那么您之前可能已經在集成測試中使用過它們。 新人是@WebAppConfiguration 。

    這些批注協同工作以配置您的測試環境。 @RunWith告訴JUnit使用Spring JUnit類運行器運行測試。 @WebAppConfiguration告訴SpringJUnit4ClassRunner集成測試要加載的ApplicationContext應該是WebApplicationContext ,而@ContextConfiguration用于指定加載哪個XML文件以及從何處加載。

    在這種情況下,我正在加載項目的“ servlet-context.xml”和“ data.xml”文件。 “ servlet-context.xml”文件包含Spring Web應用程序所需的所有標準位,例如<annotation-driven />和視圖解析器,而“ data.xml”則包含該應用程序的Spring Social組件。 這里要注意的一點是,我故意使用
    我想運行端到端集成測試來訪問文件系統,數據庫等的偽生產配置文件。

    這只是示例代碼,在集成測試中通常不會涉及生產數據庫或其他相關資源。 通常,您將配置您的應用程序以訪問集成測試數據庫和其他資源。 解決此問題的一種方法是創建一個測試 XML配置文件。 但是,不要像我在一個項目中看到的那樣,為項目中的每個Maven模塊創建單獨的測試 XML文件。 原因是當您對代碼進行更改時,最終要更改一大堆配置文件才能使集成測試再次正常工作,這既無聊又耗時。 更好的方法是擁有一個版本的XML配置,并使用Spring配置文件為不同的環境配置應用程序。 如果確實選擇使用配置文件,則還需要將@ActiveProfiles(“profile-name”)批注添加到上面列出的其他三個批注中。 但是,這超出了本博客的范圍。

    假設您使用的是自動裝配,并且您已經正確設置了<context:component-scan /> ,那么下一步就是將以下實例變量添加到測試類中:

    @Autowired private WebApplicationContext wac;

    這告訴Spring將先前創建的WebApplicationContext注入到測試中。 然后,可以在非常簡單的一行setup()方法中使用它:

    @Before public void setUp() throws Exception { mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); }

    類似于此測試的“獨立” /“編程”版本, setup()方法的目的是創建一個mockMvc實例,然后使用它來執行測試。 此處的區別在于,它只是通過使用WebApplicationContext作為MockMvcBuilders的參數來MockMvcBuilders 。

    整理好setup()方法后,接下來要做的是編寫一個測試,我將從上一個博客中重寫testShowPostsForUser_user_is_not_signed_in()作為集成測試。 令人驚訝的是,該代碼比以前的JUnit版本更簡單:

    @Test public void testShowPostsForUser_user_is_not_signed_in() throws Exception { ResultActions resultActions = mockMvc.perform(get("/posts").accept(MediaType.ALL)); resultActions.andExpect(status().isOk()); resultActions.andExpect(view().name("signin")); }

    如果將此代碼與我以前的博客中的testShowPostsForUser_user_is_not_signed_in()代碼進行比較,您會發現它幾乎相同。 唯一的區別是無需設置任何模擬對象。

    在這一點上,我將演示testShowPostsForUser_user_is_signed_in測試的集成測試版本,但這確實有些棘手。 原因是要掌握他們的Facebook帖子列表,用戶必須登錄其Facebook帳戶,這意味著在正確的必要HttpServletRequest對象之前,需要對服務器進行多次順序調用狀態以方便致電Facebook檢索帖子列表。 對于示例代碼來說,這似乎有點太復雜了,這是我不想在
    真實的項目。

    我不是將這種復雜性視為Spring MVC測試框架的局限性,而是要強調最佳實踐,這是確保對服務器的調用盡可能獨立且原子。

    當然,我可以使用模擬對象或創建虛擬Facebook服務,但是,這超出了本博客的范圍。

    一個獨立的一個很好的例子,原子服務器調用是REST調用testConfirmPurchases_selection_1_returns_a_hat(...)用于測試的OrderController從我采取類的Spring MVC,Ajax和JSON第2部分-服務器端代碼博客。 此代碼在Ajax博客中進行了全面描述,它請求購買確認,并以JSON的形式返回。

    下面OrderController了返回JSON的OrderController代碼:

    /** * Create an order form for user confirmation */ @RequestMapping(value = "/confirm", method = RequestMethod.POST) public @ResponseBody OrderForm confirmPurchases(@ModelAttribute("userSelections") UserSelections userSelections) { logger.debug("Confirming purchases..."); OrderForm orderForm = createOrderForm(userSelections.getSelection()); return orderForm; } private OrderForm createOrderForm(List<String> selections) { List<Item> items = findItemsInCatalogue(selections); String purchaseId = getPurchaseId(); OrderForm orderForm = new OrderForm(items, purchaseId); return orderForm; } private List<Item> findItemsInCatalogue(List<String> selections) { List<Item> items = new ArrayList<Item>(); for (String selection : selections) { Item item = catalogue.findItem(Integer.valueOf(selection)); items.add(item); } return items; } private String getPurchaseId() { return UUID.randomUUID().toString(); }

    盡管它返回的JSON看起來像這樣:

    {"items":[{"id":1,"description":"description","name":"name","price":1.00}, {"id":2,"description":"description2","name":"name2","price":2.00}],"purchaseId":"aabf118e-abe9-4b59-88d2-0b897796c8c0"}

    下面以冗長的樣式顯示了測試testConfirmPurchases_selection_1_returns_a_hat(...)的代碼。

    @Test public void testConfirmPurchases_selection_1_returns_a_hat() throws Exception { final String mediaType = "application/json;charset=UTF-8"; MockHttpServletRequestBuilder postRequest = post("/confirm"); postRequest = postRequest.param("selection", "1"); ResultActions resultActions = mockMvc.perform(postRequest); resultActions.andDo(print()); resultActions.andExpect(content().contentType(mediaType)); resultActions.andExpect(status().isOk()); // See http://goessner.net/articles/JsonPath/ for more on JSONPath ResultMatcher pathMatcher = jsonPath("$items[0].description").value("A nice hat"); resultActions.andExpect(pathMatcher); }

    上面的代碼不是Spring Guys希望您編寫的代碼; 但是,以冗長的格式更容易討論正在發生的事情。 該方法的結構類似于第1部分中討論的testShowPostsForUser_user_is_signed_in(...)方法。第一步是使用靜態MockMvcRequestBuilders.post(...)方法創建MockHttpServletRequestBuilder類型的postRequest對象。 值"1"的"selection"參數將添加到結果對象中。

    然后將postRequest傳遞給mockMvc.perform(...)方法,并返回一個ResultActions對象。

    然后使用andExpect(...)方法驗證ResultActions對象,以檢查HTTP狀態(ok = 200)和內容類型為"application/json;charset=UTF-8" 。

    此外,我還添加了一個andDo(print())方法調用,以顯示HttpServletRequest和HttpServletResponse對象的狀態。 該調用的輸出如下所示:

    MockHttpServletRequest:HTTP Method = POSTRequest URI = /confirmParameters = {selection=[1]}Headers = {}Handler:Type = com.captaindebug.store.OrderControllerMethod = public com.captaindebug.store.beans.OrderForm com.captaindebug.store.OrderController.confirmPurchases(com.captaindebug.store.beans.UserSelections)Resolved Exception:Type = nullModelAndView:View name = nullView = nullModel = nullFlashMap:MockHttpServletResponse:Status = 200Error message = nullHeaders = {Content-Type=[application/json;charset=UTF-8]}Content type = application/json;charset=UTF-8Body = {"items":[{"id":1,"description":"A nice hat","name":"Hat","price":12.34}],"purchaseId":"d1d0eba6-51fa-415f-ac4e-8fa2eaeaaba9"}Forwarded URL = nullRedirected URL = nullCookies = []

    最后一項測試使用靜態MockMvcResultMatchers.jsonPath(...)檢查"$items[0].description"的JSON路徑的值是否為"A nice hat" 。 為了使用jsonPath(...)靜態方法,您必須在POM.xml中包含JSON Path模塊以解析JSON。

    <dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>0.8.1</version><scope>test</scope></dependency>

    JSonPath是一種從JSon數據中選擇性提取字段的方法。 它基于XML的XPath思想。

    顯然,我上面用過的冗長風格不需要編寫測試。 下面的代碼顯示與Spring的Guy設計的相同代碼:

    @Test public void testConfirmPurchases_spring_style() throws Exception { mockMvc.perform(post("/confirm").param("selection", "1")).andDo(print()) .andExpect(content().contentType("application/json;charset=UTF-8")) .andExpect(status().isOk()) .andExpect(jsonPath("$items[0].description").value("A nice hat")); }

    所以,僅此而已。 概括地說,我們的想法是向您的單元測試中添加適當的注釋,以便Spring加載您的XML配置以創建WebApplicationContext 。 然后將其注入到您的測試中,并在創建mockMvc時作為參數傳遞給Spring MVC Test框架。 然后編寫測試,其想法是將適當構造的MockMvcRequestBuilders對象傳遞給mockMvc.perform(...)方法,然后將其返回值聲明為通過或失敗測試。

    該博客的代碼可在GitHub上找到: https : //github.com/roghughe/captaindebug/在Facebook和Ajax-JSON項目中。

    參考: Spring的MVC測試框架入門–第2部分,來自我們的JCG合作伙伴 Roger Hughes,來自Captain Debug的Blog博客。

    翻譯自: https://www.javacodegeeks.com/2013/07/getting-started-with-springs-mvc-test-framework-part-2.html

    總結

    以上是生活随笔為你收集整理的Spring MVC测试框架入门–第2部分的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。