Springboot單元測試(MockBean||SpyBean)
阿新 • • 發佈:2018-08-28
比較 spa obj 影響 package error java 執行 str
轉載: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
Springboot單元測試(MockBean||SpyBean)