單元測試之初步使用篇(testng + jmockit + springboot)
單元測試研究
(testng + jmockit + springboot)
環境配置可以參考最下面的參考資料,其中已經非常清晰了。這裡不再描述了
引入spring自動配置
- 利用spingTesting 直接使用@ContextConfiguration
//1.ContextConfiguration中注入所需要的類,由於UserServiceImpl中@Autowired了UserInfoDao、AccountDao、 OssConfig,所以都需要注入。
@ContextConfiguration(classes = {UserServiceImpl.class, UserInfoDaoImpl.class,
AccountDaoImpl.class, OssConfig.class})
//2.需要繼承AbstractTestNGSpringContextTests類
public class UserServiceImplTest extends AbstractTestNGSpringContextTests {
@Autowired
private UserServiceImpl serviceInterface;
@Test
public void testSpringAutoConfig(){
Person abc = serviceInterface.getUserInfoByName("abc");
System.out.println(abc);
}
}
//3. UserServiceImpl、UserInfoDaoImpl、AccountDaoImpl修飾@Component
- 利用配置類@Configuration結合@ContextConfiguration
利用一個配置類config.java配置完依賴之後,利用
@ContextConfiguration(classes = Config.class),其他操作和1一樣。 - 利用springBootTesting
@SpringBootTest(classes = {UserServiceImpl.class, UserInfoDaoImpl.class,
AccountDaoImpl.class, OssConfig.class})
public class UserServiceImplTest extends AbstractTestNGSpringContextTests {
@Autowired
private UserServiceImpl serviceInterface;
@Test
public void testSpringAutoConfig(){
Person abc = serviceInterface.getUserInfoByName("abc");
System.out.println(abc);
}
}
其他和@ContextConfiguration一樣,springboottest也可以使用@Configuration方式
4. 可以使用@SpringBootConfiguration(沒有研究跳過)
5. 使用@ComponentScan掃描Bean,前面都是使用@SpringBootTest或@ContextConfiguration(classes = {….})裝配bran,還可以使用@ComponentScan去掃描指定路徑
@SpringBootTest
@ComponentScan(basePackages = "com.dullbird")
//其中使用@SpringBootTest(classes = {OssConfig.class})或者@ContextConfiguration總是獲取不到配置檔案的值,但是使用ComponentScan可以獲取到。
//OssConfig 類如下
@Component
@ConfigurationProperties(prefix = "oss")
public class OssConfig {
private String endpoint;
private String outEndpoint;
private String accessKeyId;
private String accessKeySecret;
private String readPublicBucket;
//省略get和set方法
}
- 使用@SpringBootApplication配置
@SpringBootTest
/**
* 使用SpringBootTest和ContextConfiguration,載入配置檔案沒有值,增加ComponentScan掃描就有值
*/
@SpringBootApplication(scanBasePackages = "com.dullbird")
[email protected]會覆蓋之前的配置。
@SpringBootApplication(scanBasePackages = "com.dullbird")
@TestPropertySource(properties = {"oss.accessKeyId = aaaaaa"})
mock物件或方法基於jmockit
比如測試類A,類A注入了bean B和C,測試A的方法時,呼叫了B和C的方法。這樣就引入了很多變數,需要用mock的方式把B和C的方法表現mock掉。接下來有幾種場景。
示例程式碼:
//介面
public interface ServiceInterface {
Person getUserInfoByName(String name);
}
public interface AccountDao {
String getAccountTest(String name);
}
public interface UserInfoDao {
Person getUserInfoByName(String name);
String getTestWord(String context);
}
@Component
public class AccountDaoImpl implements AccountDao {
@Override
public String getAccountTest(String name) {
return name;
}
}
@Component
public class UserInfoDaoImpl implements UserInfoDao {
@Override
public Person getUserInfoByName(String name) {
return new Person(name, "18");
}
@Override
public String getTestWord(String context) {
return context;
}
}
@Component
public class UserServiceImpl implements ServiceInterface {
public static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
@Autowired
private AccountDao accountDao;
@Autowired
private UserInfoDao userInfoDao;
@Autowired
private OssConfig ossConfig;
//需要測試的方法
@Override
public Person getUserInfoByName(String name) {
logger.info("進入類UserServiceImpl,獲取的引數name={}", name);
String testWord = userInfoDao.getTestWord(name);
logger.info("====testWord======================={}", testWord);
String accountTest = accountDao.getAccountTest(name);
logger.info("===accountTest========================{}", accountTest);
//可以忽略
logger.info("===ossConfig========================{}", ossConfig.getAccessKeyId());
return userInfoDao.getUserInfoByName(name);
}
}
1.全部都不mock程式碼,僅僅注入
@SpringBootTest
@SpringBootApplication(scanBasePackages = "com.dullbird")
public class UserServiceImplTest extends AbstractTestNGSpringContextTests {
@Autowired
private UserServiceImpl serviceInterface;
@Test
public void testServiceInterface() throws Exception {
Person abc = serviceInterface.getUserInfoByName("abc");
System.out.println(abc);
}
2. mock部分內容,比如例子中,僅僅希望mock部分程式碼。比如僅mock類userInfoDao的getTestWord(String name )方法和accountDao.getAccountTest(String name)方法。
@SpringBootTest
@SpringBootApplication(scanBasePackages = "com.dullbird")
public class UserServiceImplTest extends AbstractTestNGSpringContextTests {
//首先需要mock的物件需要注入,這裡要對比一個@Injectable註釋
@Autowired
private AccountDao accountDao;
@Autowired
private UserInfoDao userInfoDao;
@Autowired
private UserServiceImpl serviceInterface;
@Test
public void testServiceInterface() throws Exception {
//進行mock,需要注意傳入了引數userInfoDao,表示僅僅mock例項userInfoDao的getTestWord方法,可以看到userInfoDao.getUserInfoByName方法的表現還是原來的樣子。下面會介紹一下Expectations。
new Expectations(userInfoDao){
{
userInfoDao.getTestWord(anyString);
result = "userInfoDao mock result";
}
};
new Expectations(accountDao){
{
accountDao.getAccountTest(anyString);
result = "accountDaoImpl mock result ";
}
};
Person abc = serviceInterface.getUserInfoByName("abc");
System.out.println(abc);
}
}
如果使用@Injectable測試一下
@Autowired
@Injectable
private UserInfoDao userInfoDao;
說明了一種情況,如果使用@Injectable修飾例項,例項所有的方法都會返回預設值。比如:
Person getUserInfoByName(String name);
String getTestWord(String context);
兩個方法返回的都是null, 基本型別的返回0.如果其中方法被mock。會按照mock來表現。
Expectations使用
//引數可以傳入a.class或者例項,如果傳入例項,那麼僅僅mock部分方法。如果傳入.class會mock所有方法
new Expectations(){
{
a.getTest();
result = null;
times =1;//呼叫次數,僅呼叫一次
a.test();
result = "two";
times =1;
//如果使用了Expectations,那麼Expectations裡面mock的方法都需要呼叫,並且需要按照順序。按照當前例子,需要先呼叫a.getTest(),再呼叫a.test()。如果多呼叫或者少呼叫,就會報錯。如果需要mock方法,但是不一定呼叫,需要使用NonStrictExpectations,使用方法一樣。呼叫沒有嚴格要求。
}
}
@Tested標籤(概念沒有那麼理解)
JMockit會自動建立註解為“@Tested”的類物件,並將其做為被測試物件。“@Tested”標註的必須是實體,不能是介面。否則會報錯
比如上面例子中UserServiceImpl serviceInterface;就是我們需要的測試物件。
@SpringBootTest
@SpringBootApplication(scanBasePackages = "com.dullbird")
public class UserServiceImplTest extends AbstractTestNGSpringContextTests {
@Injectable
private AccountDao accountDao;
@Injectable
private UserInfoDao userInfoDao;
//這裡雖然注入了ossConfig,但是由於@Injectable標籤。ossConfig的所有方法獲取的值都是null或者0
@Autowired
@Injectable
private OssConfig ossConfig;
/**
*如果使用@Tested描述,那麼UserServiceImpl注入的物件都需要@Injectable,否則會報錯,官方有提到部分mock,但 是這裡我沒有嘗試成功
*/
@Tested
private UserServiceImpl serviceInterface;
@Test
public void testServiceInterface() throws Exception {
new Expectations(){
{
userInfoDao.getTestWord(anyString);
result = "userInfoDao mock result";
}
};
new Expectations(){
{
accountDao.getAccountTest(anyString);
result = "accountDaoImpl mock result ";
}
};
Person abc = serviceInterface.getUserInfoByName("abc");
System.out.println(abc);
System.out.println(abc.getName());
System.out.println(abc.getAge());
}
}
留下的問題
- 需要自己研究的是不同的mock的作用範圍,有的是類級別的,有的是用例級別的。這個還沒有具體整理處理。
- @Tested是否是必須的,使用場景。根據官方文件說明的部分mock我還沒有實現。
參考資料
相關推薦
單元測試之初步使用篇(testng + jmockit + springboot)
單元測試研究 (testng + jmockit + springboot) 環境配置可以參考最下面的參考資料,其中已經非常清晰了。這裡不再描述了 引入spring自動配置 利用spingTesting 直接使用@ContextConfigurat
Java單元測試之JUnit篇
JUnit4通過註解的方式來識別測試方法。目前主要註解有: @BeforeClass 全域性只會執行一次,而且是第一個執行,且必須為static void @Before 在測試方法執行之前執行,即初
補習系列-springboot 單元測試之道
try 精彩 一次 run rest spec ner hat ltm 目錄 目標 一、About 單元測試 二、About Junit 三、SpringBoot-單元測試 項目依賴 測試樣例 四、Mock測試 五、最後 目標 了解 單元測試的背景 了解如何 利用
談談單元測試之(四):測試工具 TestNG
前言 上一篇文章《測試工具 JUnit 4》中提到了 JUnit 4,並對 JUnit 4 做了簡單的討論,這篇文章我們將要圍繞另一款測試工具討論 —— TestNG。其實,這篇文章應該寫在《測試工具 JUnit 3》之後,和《測試工具 JU
.net core 單元測試之 JustMock第一篇
前面介紹了單元測試的框架NUnit,它可以很好的幫助我們建立測試,檢驗我們的程式碼是否正確。但這還不夠,有時候我們的業務比較重,會依賴其它的類。基於隔離測試的原則,我們不希望依賴的其它類影響到我們的測試目標。這時候Mock就顯得十分重要了。當然還有其它因素使得我們必須Mock物件,比如配置檔案,DB等。 提供
.net core 單元測試之 JustMock第二篇
JustMock標記方法 上篇文章在舉例子的時候使用了returns的標記方法,JustMock還有很多標記方法: CallOriginal 跟Behaviors裡的CallOriginal差不多意思,被呼叫時執行原始的方法和屬性的實現。 DoNothing 忽略對方法或者屬性的呼叫。 DoInstead
單元測試之Stub和Mock
下載 我們 並且 試用 sample 註入 mes oge new 單元測試之Stub和Mock FROM:http://www.cnblogs.com/TankXiao/archive/2012/03/06/2366073.html 在做單元測試的時候,我們會發現我
python + unittest 做單元測試之學習筆記
stl unittest 例子 gin pre log script 有關 assert 單元測試在保證開發效率、可維護性和軟件質量等方面有很重要的地位,所謂的單元測試,就是對一個類,一個模塊或者一個函數進行正確性檢測的一種測試方式。 這裏主要是就應用 python + u
論單元測試之重要性
表單 曾經 mybatis 服務 request 第一個 完成 分離 能說 單元測試的重要性不言而喻,自我開發生涯以來,從很少註釋過過場場,到非常重視。 單元測試為什麽會讓人忽視呢? 通常情況像一些查詢或者增刪改之類,拿我來說,即便報錯我大概一掃,我就知道錯誤是什麽了,該如
python筆記24-unittest單元測試之mock.patch
rom Coding int self. 錯誤 測試用例 方法 org auto 前言 上一篇python筆記23-unittest單元測試之mock對mock已經有初步的認識, 本篇繼續介紹mock裏面另一種實現方式,patch裝飾器的使用,patch() 作為函數裝飾器
軟件測試之兵器篇——測試工具【轉】
電話 跨項目 spa studio 桌面應用 mar 設備 也有 gin 功能測試篇 功能測試,是軟件測試裏的入門級心法,自然也有與之相對應的兵器來發揮心法的最大功力。 1) 屠龍刀之QTP 屠龍刀是金庸小說裏排名第一的寶刀,重劍無鋒,無堅不摧。素有“武林至尊,寶刀屠
單元測試之Mock(Moq)
inter 商品 void 簡單 calc 不用 準備 targe ted Mock翻譯為“嘲弄”,其實就是偽造一個對象用於測試。在單元測試中,被測試方法依賴於其他對象時,為了測試簡單一般“偽造”一個這個對象;這樣做的目的: 不用考慮依賴對象的復雜性(方便準備測試數據)
java單元測試之如何實現非同步介面的測試案例
測試是軟體釋出的重要環節,單元測試在實際開發中是一種常用的測試方法,java單元測試主要用junit,最新是junit5,本人開發一般用junit4。因為單元測試能夠在軟體模組組合之前儘快發現問題,所以實際開發中投入產出比很高。實際使用難免會遇到非同步操作的介面測試,最常用的情景是別人家的SD
前端單元測試之Jest
概述 關於前端單元測試的好處自不必說,基礎的介紹和知識可以參考之前的部落格連結:React Native單元測試。在軟體的測試領域,測試主要分為:單元測試、整合測試和功能測試。 單元測試:在計算機程式設計中,單元測試(英語:Unit Testing)又稱為模組測試, 是針對程式模組(軟體設計的最小單
spring boot單元測試之druid NullPointException
最近在使用spring boot 對 Controller 進行單元測試時,發現 druid 竟然丟擲了空指標異常。原因是,使用了druid的監控,需要經過druid的 Filter 攔截器,但是spr
powermockito單元測試之深入實踐
概述 由於最近工作需要, 在專案中要做單元測試, 以達到指定的測試用例覆蓋率指標。專案中我們引入的powermockito來編寫測試用例, JaCoCo來監控單元測試覆蓋率。關於框架的選擇, 網上討論mockito和powermockito孰優孰劣的文章眾多, 這裡就不多做闡述, 讀者如有興趣可自行了解。
phpunit 單元測試之程式碼覆蓋率
最近團隊在不斷完善專案中的單元測試用例,會用到程式碼覆蓋率分析,本來以為 homestead 應該預設安裝了 xdebug ,所以使用 phpunit --coverage-html ./tests/codeCoverage 來生成 html 報告,但是執行後提示如下錯誤 Error: No
談談單元測試之(三):測試工具 JUnit 4
前言 上一篇文章《測試工具 JUnit 3》簡單的討論了 JUnit 3 的使用以及內部的方法。這篇文章將會在 JUnit 3 的基礎上,討論一下 JUnit 4 的新特性。同時,與 JUnit 3 做一個簡單的對比。那麼,廢話就不多說了,直
談談單元測試之(二):測試工具 JUnit 3
前言 上一篇文章《 為什麼要進行煩人的單元測試?》討論了一下現階段軟體開發中,程式設計師們測試情況的現狀。這篇文章中,我打算介紹一下單元測試的工具(外掛),並且推薦大家以後在開發中,真正的用上單元測試,用好單元測試。
談談單元測試之(一):為什麼要進行煩人的單元測試?
前言 最近,在網上看到過一個調查,調查的內容是“程式設計師在專案開發中編寫單元測試的情況”。當然,至於調查的結果,我想聰明的你已經可以猜到了。高達 58.3% 的比例,一般情況下不寫單元測試,只有偶爾的情況才會寫寫。16.6%