Springboot單元測試(MockBean||SpyBean)


轉載:https://blog.csdn.net/maiyikai/article/details/78483423

本來要寫springboot集成netty實現的,但是想起來單元測試沒總結,那就趁此機會總結一下,不用文字了,直接用代碼去實現: 
創建一個放方法的類MethodTest.java:(命名不嚴謹,能看懂就行了)

package com.mtk.netty.test; import org.springframework.stereotype.Component; @Component public class MethodTest { //主方法 public String gg(boolean flag){ System.err.println("coming........."); String d = g(flag);//子方法 h(); System.err.println("result data is "+d); return d; } public String g(boolean flag){ System.err.println("coming.........g"); if(flag){ throw new IllegalAccessError();//flag為true時拋異常 } return "d"; } public void h(){ System.err.println("coming.........h"); } }

使用上邊的方法類,寫單元測試: 
這里時spy方式:

package com.mtk.netty.test; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import com.myk.Application; /** * 使用spy方式 * @author maiyikai 2017.11.08 * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = Application.class) @WebAppConfiguration public class SpyTest { //gg(boolean)方法:控制台打印: coming......... //g(boolean)方法:控制台打印: coming.........g //h()方法:控制台打印: coming.........h //gg(boolean)方法在g(boolean)和h()方法執行完之后:控制台打印: result data is * /** * 使用代理:如下方式 * 或Mockito.spy(MethodTest.class)獲得代理對象 */ @SpyBean private MethodTest spyTest; /** * 不代理,直接運行程序 * 控制台打印: * coming......... * coming.........g * coming.........h * result data is d * d */ @Test public void test(){ System.err.println(spyTest.gg(false)); } /** * 不使用代理:讓g方法拋異常 * 控制台打印 * coming......... * coming.........g * 由於拋異常,程序中斷 */ @Test public void test2(){ System.err.println(spyTest.gg(true)); } /** * 使用代理對象,代理g方法,並讓其返回“test” * 第一種方式:使用thenReturn("test"); * 控制台打印: * coming.........g * coming......... * coming.........h * result data is test * test * */ @Test public void test3(){ Mockito.when(spyTest.g(false)).thenReturn("test"); System.err.println(spyTest.gg(false)); } /** * 使用代理對象,代理g方法,並讓其返回“test” * 第二種方式:使用doReturn("test"); * 其中doReturn("test")后執行.when(spyTest).g(false)方法 * 控制台打印: * coming......... * coming.........h * result data is test * test * */ @Test public void test4(){ Mockito.doReturn("test").when(spyTest).g(false); System.err.println(spyTest.gg(false)); } /** * test3-test4比較 * 正常執行順序 * coming......... * coming.........g * coming.........h * result data is d * d * 使用Mockito.when(spyTest.g(false)).thenReturn("test");方式 * g(boolean)方法會在調用主方法gg(boolean)前執行,不管執行的結果是啥,都會按照mock的數據“test”返回 * * 使用Mockito.doReturn("test").when(spyTest).g(false);方式 * g(boolean)方法不會被執行,當時會將它的返回值賦值為:“test”。 * 在主方法gg(boolean)執行到g(boolean)時,不執行g(boolean)方法體,直接將值“test'”返回。后續方法照常執行 */ //####################################################################################### /** * 使用代理對象,代理gg方法,並讓其返回“test” * 第一種方式:使用thenReturn("test"); * 控制台打印: * coming.........g * */ @Test public void test5(){ Mockito.when(spyTest.g(true)).thenReturn("test"); System.err.println(spyTest.gg(true)); } /** * 使用代理對象,代理gg方法,並讓其返回“test” * 第二種方式:使用doReturn("test"); * 其中doReturn("test")后執行.when(spyTest).g(true)方法--拋異常 * 控制台打印: * coming......... * coming.........h * result data is test * test * */ @Test public void test6(){ Mockito.doReturn("test").when(spyTest).g(true); System.err.println(spyTest.gg(true)); } /** * test5-test6比較 * 故意賦值讓其方法拋異常。 * 正常執行順序 * coming......... * coming.........g * coming.........h * result data is d * d * * 因為:Mockito.when(spyTest.g(true)).thenReturn("test");會執行方法體的內容,則g(boolean)方法體會被執行,會拋出異常中斷程序運行 * 而Mockito.doReturn("test").when(spyTest).g(true);方法體不會被執行,則不會拋出異常,不會造成程序中斷 */ //##################################無返回值###################### /** * 無返回值方法的代理 * 方法為h() * 因此方法對代碼不造成任何影響,所以可以不執行它 * 可以使用:doNothing * 代碼:Mockito.doNothing().when(spyTest).h(); */ @Test public void test7(){ Mockito.doNothing().when(spyTest).h(); System.err.println(spyTest.gg(false)); } /** * 測試 * coming......... * coming.........g * result data is d * d */ @Test public void test10(){ Mockito.doReturn("23").when(spyTest).g(true); Mockito.doNothing().when(spyTest).h(); System.err.println(spyTest.gg(false)); } }

這里時mock的方式:

package com.mtk.netty.test; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import com.myk.Application; /** * 使用mock方式 * @author maiyikai 2017.11.08 * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = Application.class) @WebAppConfiguration public class MockTest { //gg(boolean)方法:控制台打印: coming......... //g(boolean)方法:控制台打印: coming.........g //h()方法:控制台打印: coming.........h //gg(boolean)方法在g(boolean)和h()方法執行完之后:控制台打印: result data is * /** * 使用代理:如下方式 * 或Mockito.mock(MethodTest.class)獲得代理對象 */ @MockBean private MethodTest mockTest; /** * 使用mock方式將會把對象給mock掉,則對象中的方法將不會被執行,但是使用到某方法時可以mock值,供調用方法使用 */ /** * 訪問主方法體gg(boolean) * 返回null */ @Test public void test1(){ System.err.println(mockTest.gg(false)); } /** * mock方法gg(boolean),使其在使用到gg(boolean)方法時,返回:"test" */ @Test public void test2(){ Mockito.when(mockTest.gg(false)).thenReturn("test"); System.err.println(mockTest.gg(false)); } /** * mock方法gg(boolean),使其在使用到gg(boolean)方法時,返回:"test" */ @Test public void test3(){ Mockito.doReturn("test").when(mockTest).gg(false); System.err.println(mockTest.gg(false)); } /** * mock方法gg(boolean),使其在使用到gg(boolean)方法時,返回:"test" */ @Test public void test4(){ Mockito.when(mockTest.gg(false)).thenAnswer(new Answer<String>() { //Answer<T> T為方法的返回值類型 @Override public String answer(InvocationOnMock invocation) throws Throwable { return "test"; } }); System.err.println(mockTest.gg(false)); } /** * mock方法gg(boolean),使其在執行到此方法時拋出自定義異常 */ @Test public void test5(){ Mockito.when(mockTest.gg(false)).thenThrow( new IllegalArgumentException("單元測試異常")); System.err.println(mockTest.gg(false)); } //對與返回值類型為void的操作有 //1.直接mock對象,即此對象中所有的方法都不會被執行 //2.使用Mockito.doNothing().when(mockObject).method();標記執行該方法時不做任何操作 }

因時間有限,寫了一些簡單的操作; 
寫單元測試的過程中,有想過“只需要mock方法類中的某個方法,其他的方法不受影響”;之前使用MockBean就出問題了,研究了一下使用SpyBean就可以使用了,可以看上邊的例子就可以知道了。 
springboot的文檔介紹也是可以看的:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html “springboot 
我的項目上傳地址:http://download.csdn.net/download/maiyikai/10110450 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM