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

歡迎訪問 生活随笔!

生活随笔

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

javascript

junit 内部类测试_Springboot 使用单元测试

發布時間:2024/9/19 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 junit 内部类测试_Springboot 使用单元测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文公眾號來源:美碼師作者:美碼師本文已收錄至我的GitHub

目標

  • 了解 單元測試的背景

  • 了解如何 利用 springboot 實現接口的測試

  • 了解如何 利用 mokito 做代碼的 mock

  • 一、About 單元測試

    單元測試其實是一種廉價的技術,是由開發者創建運行測試代碼,用于對程序模塊(軟件設計的最小單位)進行正確性檢驗的一種做法。 而所謂的最小單元,就是指應用的最小可測試部件。 在面向對象領域,最小單元對應于類的某個成員方法。

    通常意義的單元測試會用于驗證某場景、某條件下某方法的行為結果,舉個例子:

    我想驗證

    ? ?Equals 方法,在兩個對象類型不一致時應該返回 false

    單元測試的初衷,是對各個相互獨立,互不影響的基本單元基線測試,以此來保證核心代碼的質量。

    每一段單元測試代碼,都一定會包含幾個部分

    • Arrange 用于初始化一些被測試方法需要的參數或依賴的對象。

    • Act方法 用于調用被測方法進行測試。

    • Assert?

    ? ? ? ?用于驗證測試方法是否按期望執行或者結果是否符合期望值

    See !并不是很復雜,可是大多數開發者并不喜歡做單元測試。 而且,有一個現象很有意思,水平越高的程序員,越不喜歡寫測試代碼,why?

    “ 因為單元測試,主要是用來防低級程序員挖坑的啊 ”

    這句話不是我說的,但卻代表了相當一部分程序員的心聲..

    那么,單元測試到底要不要做,并不是本文要討論的問題。 建議大家閱讀下 《單元測試之道-Java版本》 (程序員修煉三部曲系列)這邊書,看完后再做出自己的理解。

    為了測試一座橋梁,不應該只在晴朗的天氣,開一輛汽車從橋中間穿過,就認為已經完成了對橋梁的測試

    二、About Junit

    接下來,要說一說 Junit框架,這個是最流行的Java 單元測試框架。

    Junit 創建者是 Kent Beck 和?Erich Gamma,自其出現以來,Junit 生態圈已經非常龐大。 大量的應用程序、開發框架都以 Junit 作為標準的的基礎測試組件,這當然也包括 Spring系列的框架。

    一個典型的Junit單元測試類:

    class StandardTests {

    ? ?@BeforeClass

    ? ?static void initAll() {

    ? ?}

    ? ?@Before

    ? ?void init() {

    ? ?}

    ? ?@Test

    ? ?void justTest() {

    ? ?...

    ? ?assertTrue(...)

    ? ?}

    ? ?@After

    ? ?void tearDown() {

    ? ?}

    ? ?@AfterClass

    ? ?static void tearDownAll() {

    ? ?}

    }

    說明

    注解說明
    @BeforeClass在當前類測試之前執行
    @Before在每個測試方法之前執行
    @Test聲明測試方法
    @After在每個測試方法之后執行
    @AfterClass在當前類測試之后執行

    這幾個注解還是比較容易理解的,需要注意的只是 @BeforeClass 和 @Before,前者是一個靜態方法, 會在整個測試用例類開始前執行,僅一次;

    ?而后者則是在方法測試之前觸發,可能會執行多次。

    為了更清晰的理解Junit 是怎么運作,下面展示一個源碼片段:

    ? ?public void runBare() throws Throwable {

    ? ? ? ?Throwable exception = null;

    ? ? ? ?setUp();

    ? ? ? ?try {

    ? ? ? ? ? ?runTest();

    ? ? ? ?} catch (Throwable running) {

    ? ? ? ? ? ?exception = running;

    ? ? ? ?} finally {

    ? ? ? ? ? ?try {

    ? ? ? ? ? ? ? ?tearDown();

    ? ? ? ? ? ?} catch (Throwable tearingDown) {

    ? ? ? ? ? ? ? ?if (exception == null) exception = tearingDown;

    ? ? ? ? ? ?}

    ? ? ? ?}

    ? ? ? ?if (exception != null) throw exception;

    ? ?}

    這是早期版本的TestCase類其中的一段實現,與我們所說的思路是基本一致的! 然而,基于注解的實現是由 Junit4提供的,在有興趣的話可以深入看看源碼。

    關鍵詞

    TestCase、JUnit4TestAdapter、BlockJUnit4ClassRunner

    三、SpringBoot-單元測試

    SpringBoot 提供了 spring-boot-starter-test 用于實現單元測試。

    項目依賴

    org.springframework.boot

    spring-boot-starter-test

    ${spring-boot.version}

    測試樣例

    @RunWith(SpringRunner.class)

    @SpringBootTest(classes = DemoBoot.class)

    public class RestApiTest {

    ? ?private MockMvc mockMvc;

    ? ?private ObjectMapper mapper = new ObjectMapper();

    ? ?@Autowired

    ? ?private WebApplicationContext context;

    ? ?@Autowired

    ? ?private RestDataManager dataManager;

    ? ?private static final String CUSTOMER = "LiLei";

    ? ?private Pet polly;

    ? ?private Pet badboy;

    ? ?@Before

    ? ?public void setupMockMvc() throws Exception {

    ? ? ? ?mockMvc = MockMvcBuilders.webAppContextSetup(context).build();

    ? ? ? ?initData();

    ? ?}

    ? ?private void initData() {

    ? ? ? ?// 清除原有寵物信息

    ? ? ? ?dataManager.clearPets(CUSTOMER);

    ? ? ? ?// 添加新的寵物信息

    ? ? ? ?polly = new Pet();

    ? ? ? ?polly.setType("Bird");

    ? ? ? ?polly.setName("Polly");

    ? ? ? ?polly.setDescription("the rapid speaker");

    ? ? ? ?dataManager.addPet(CUSTOMER, polly);

    ? ? ? ?badboy = new Pet();

    ? ? ? ?badboy.setType("Dog");

    ? ? ? ?badboy.setName("BadBoy");

    ? ? ? ?polly.setDescription("the monster");

    ? ? ? ?dataManager.addPet(CUSTOMER, badboy);

    ? ?}

    ? ?@Test

    ? ?public void testGet() throws Exception {

    ? ? ? ?mockMvc.perform(MockMvcRequestBuilders.get("/rest/pets/{customer}/{petId}",

    ? ? ? ? ? ? ? ?CUSTOMER, polly.getPetId()))

    ? ? ? ? ? ? ? ?.andExpect(MockMvcResultMatchers.status().isOk())

    ? ? ? ? ? ? ? ?.andExpect(MockMvcResultMatchers.content()

    ? ? ? ? ? ? ? ? ? ? ? .contentType(MediaType.APPLICATION_JSON_UTF8))

    ? ? ? ? ? ? ? ?.andExpect(MockMvcResultMatchers.content()

    ? ? ? ? ? ? ? ? ? ? ? .json(mapper.writeValueAsString(polly)))

    ? ? ? ? ? ? ? ?.andDo(MockMvcResultHandlers.print());

    ? ?}

    }

    說明

    SpringRunner繼承于SpringJUnit4ClassRunner,這是Spring框架基于Junit實現的基礎類。

    如果還記得前面提到的 BlockJUnit4ClassRunner,應該不難猜到,Spring 的實現類集成了該類。

    那么,SpringRunner 做了什么? 什么也沒有,只是一個名稱的修正而已(論命名的重要性)

    @SpringBootTest的作用

    其代碼注釋如下:

    Annotation that can be specified on a test class that runs Spring Boot based tests.

    Provides the following features over and above the regular Spring TestContext Framework:

    1. Uses SpringBootContextLoader as the default ContextLoader when no specific @ContextConfiguration(loader=...) is defined.

    2. Automatically searches for a @SpringBootConfiguration when nested @Configuration is not used, and no explicit classes are specified.

    3. Allows custom Environment properties to be defined using the properties attribute.

    4. Provides support for different webEnvironment modes, including the ability to start a fully running container listening on a defined or random port.

    5. Registers a TestRestTemplate bean for use in web tests that are using a fully running container.

    要點

  • 默認會使用SpringBootContextLoader類用于上下文加載, 這個類將會使用所配置的SpringBootApplication實體類作為入口,加載配置并初始化Spring上下文環境;

  • 可以支持自定義的配置,通過 Environment 屬性設置;

  • 支持不同的 web 環境模式,可以是固定端口、隨機端口、無端口幾種模式。

  • 關鍵詞

    SpringRunner、SpringBootTest、SpringBootContextLoader

    四、Mock測試

    Mock 測試的使用場景在于,被測試模塊(方法)依賴于外部系統(web服務、中間件或是數據庫)。

    我們需要提供一種快速驗證本地實現邏輯的策略,那就是 Mock,也稱為打樁。

    如上圖,A 模塊依賴于 B 模塊,在 B 模塊不可達的時候,我們對 依賴接口進行了 Mock。這樣在執行測試時,不需要真實的 B 模塊便可完成測試。

    下面我們要用到的 Mock 組件叫 Mockito

    springboot-starter-test 自帶了對于 mockito 的依賴,下面看一段代碼:

    ? ?@Before

    ? ?public void setupMockMvc() throws Exception {

    ? ? ? ?// 啟用mock

    ? ?@Before

    ? ?public void setupMockMvc() throws Exception {

    ? ? ? ?// 啟用mock

    ? ? ? ?MockitoAnnotations.initMocks(this);

    ? ? ? ?polly = new Pet();

    ? ? ? ?polly.setType("Bird");

    ? ? ? ?polly.setName("Polly");

    ? ? ? ?polly.setDescription("the rapid speaker");

    ? ? ? ?lilei = new Customer();

    ? ? ? ?lilei.setName(CUSTOMER);

    ? ? ? ?// 設置mock接口

    ? ? ? ?Mockito.when(dataManager.getPets(Mockito.isA(String.class))).thenReturn(Arrays.asList(polly));

    ? ? ? ?Mockito.when(dataManager.getCustomer(Mockito.isA(String.class))).thenReturn(lilei);

    ? ? ? ?// 使用standaloneSetup,指定controller

    ? ? ? ?// 由于不通過webappliationContext初始化,許多配置不會自動完成,此外bean的初始化方法也不會執行

    ? ? ? ?mockMvc = MockMvcBuilders.standaloneSetup(controller)

    ? ? ? ? ? ? ? ?.setMessageConverters(new MappingJackson2HttpMessageConverter()).build();

    ? ?}

    ? ? ? ?polly = new Pet();

    ? ? ? ?polly.setType("Bird");

    ? ? ? ?polly.setName("Polly");

    ? ? ? ?polly.setDescription("the rapid speaker");

    ? ? ? ?lilei = new Customer();

    ? ? ? ?lilei.setName(CUSTOMER);

    ? ? ? ?// 設置mock接口

    ? ? ? ?Mockito.when(dataManager.getPets(Mockito.isA(String.class))).thenReturn(Arrays.asList(polly));

    ? ? ? ?Mockito.when(dataManager.getCustomer(Mockito.isA(String.class))).thenReturn(lilei);

    ? ? ? ?// 使用standaloneSetup,指定controller

    ? ? ? ?// 由于不通過webappliationContext初始化,許多配置不會自動完成,此外bean的初始化方法也不會執行

    ? ? ? ?mockMvc = MockMvcBuilders.standaloneSetup(controller)

    ? ? ? ? ? ? ? ?.setMessageConverters(new MappingJackson2HttpMessageConverter()).build();

    ? ?}

    看到了嗎,利用 Mockito 可以實現你想要的 Mock效果,如下:

    Mockito.when( somemethod ).thenReturn( some thing to return);

    然而,在進行 mock 方法時,需要使用 standaloneSetup 的模式, 否則 mockito 無法工作。

    mockMvc = MockMvcBuilders.standaloneSetup(controller)..

    關鍵詞

    Mockito、MockMvcBuilders

    五、最后

    細心的讀者會發現,前面講了單元測試的對象,是指軟件設計的最小單位(方法),可是為什么到了 SpringBoot 的部分卻都是對于API(Controller層)的測試呢??

    到底我們的單元測試應該針對內部實現的某個單元,比如 DAO/Service方法,還是針對接口(API Interface)?

    筆者認為,這點并沒有絕對的好壞之分,關鍵在于取舍。?

    單元測試是軟件工程領域的概念,而軟件項目是分很多種類型的,比如在早期的軟件工程中,就有不少的基于C/S架構的程序,這類程序的體積相對龐大,往往需要對大量模塊級的方法進行單元測試;

    現如今的微服務體系架構中,對于各個子系統來說,API(作為契約)是必須進行測試的。 對于某服務的單元測試,選擇 Controller 還是 Service層,取決于你的成本效益考慮,而目前來看,結合敏捷化的 TDD實踐、 通過單元測試進行 API測試 已經是一種主流做法。

    兩年嘔心瀝血的文章「面試題」「基礎」「進階」這里全都有!

    300多篇原創技術文章加入交流群學習海量視頻資源精美腦圖面試題

    長按掃碼可關注獲取?

    在看和分享對我非常重要!

    總結

    以上是生活随笔為你收集整理的junit 内部类测试_Springboot 使用单元测试的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 91精品国产综合久久久密臀九色 | 国产xxxxx视频 | 啊v视频在线观看 | 亚洲国产免费视频 | 免费网站污 | 美丽的姑娘在线观看免费 | 免费看国产片在线观看 | 日本动漫艳母 | 亚洲精品一区久久久久久 | 欧美性猛交乱大交3 | 欧美成人综合 | 日日干夜夜操 | 色大师在线观看 | 成人三级在线看 | 亚洲一区自拍 | 成人91在线 | 久久国产欧美日韩精品 | 天天插天天爽 | 欧洲精品久久久久毛片完整版 | 色播在线 | 在线一区二区三区四区五区 | 日韩精品视频观看 | 动漫同人高h啪啪爽文 | 麻豆传媒网站 | 日韩无码专区 | 摸大乳喷奶水www视频 | 狠狠干在线观看 | 伊人春色网站 | 99精品久久99久久久久 | 秋霞福利片 | 国产精品久久久久av | 日本污污网站 | 图书馆的女友动漫在线观看 | 欧美一区二区久久久 | 大尺度av在线 | 少妇性l交大片免费观看 | 成人av专区| 国产日韩欧美视频在线 | 国产18精品乱码免费看 | 超色视频 | 尹人综合| 亚洲春色www | 外国毛片 | 一区二区三区日 | 波多野结衣中文字幕一区 | 久久av在线播放 | 激情文学综合网 | 国产毛片欧美毛片久久久 | 亚洲AV无码国产成人久久 | 在线观看国产一区二区 | 波多野结衣一本 | 男女在楼梯上高潮做啪啪 | jiizzyou性欧美老片 | 一区二区三区伦理片 | 日本在线观看一区二区 | 欧美午夜精品久久久久久浪潮 | 精人妻无码一区二区三区 | 亚洲品质自拍视频 | 欧美性一区二区三区 | 国产精品91av | 肉丝肉足丝袜一区二区三区 | 一亲二脱三插 | 香港三级日本三级韩国三级 | 欧美日韩国产一区二区三区在线观看 | 99精品视频免费看 | 撸啊撸av | 91精品综合久久久久久五月天 | 被室友玩屁股(h)男男 | 懂色一区二区三区免费观看 | 国产色播| 一个人在线观看免费视频www | 国产精品毛片久久久久久 | 国产视频福利在线 | 与子敌伦刺激对白播放的优点 | 中国在线观看免费高清视频播放 | 国产一级全黄 | 国产又粗又猛又爽又黄视频 | 日欧美女人 | 免费人成 | 91色在线播放 | 日韩色视频在线观看 | 91大片在线观看 | 婷婷激情五月综合 | 91看片看淫黄大片 | 中文字幕一区二区三区四区不卡 | 国产av剧情一区二区三区 | 国产精品一色哟哟哟 | 日韩少妇一区二区三区 | 成人在线观看一区 | av精选| 天天干免费视频 | 69久久久久| 思思99精品视频在线观看 | 一级一级黄色片 | 婷婷在线影院 | 欧美三级理论片 | 久久蜜臀 | 欧美激情一二三 | 97精品一区二区视频在线观看 |