單元測(cè)試基本概念
- SUT:被測(cè)系統(tǒng)
- Test Double:測(cè)試替身,具體有
Dummy Object
唐全,Test Stub
,Mock Object
等 - Test Fixture:測(cè)試皮具钦听,就是測(cè)試運(yùn)行程序會(huì)再測(cè)試方法之前自動(dòng)初始化逾柿,回收資源的工作。
- Test Suite:測(cè)試套件秘遏,解決每次只能運(yùn)行一個(gè)測(cè)試用例的情況丘薛,可以批量運(yùn)行。
- Assertions:斷言邦危,是測(cè)試框架里面的若干個(gè)方法洋侨,用來(lái)判斷某個(gè)語(yǔ)句的結(jié)果是否為真或判斷是否與預(yù)期相符。
JUnit4
JUnit4與之前的版本有了很多的改變倦蚪,主要是使用了Java中的Annotation
和靜態(tài)導(dǎo)入希坚,變得更加地好用了。
package cn.qingtianr.dao;
import org.junit.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
/**
* Created by jack on 16-7-3.
*/
public class ThemeMapperTest {
@BeforeClass
public static void setUpClass() throws Exception{
}
@AfterClass
public static void tearDownClass() throws Exception{
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test(expected = NullPointerException.class)//判斷是否拋出空指針異常
public void testShowAllTheme() throws Exception {
}
@Test(timeout = 10)//判斷是否執(zhí)行時(shí)間再10秒之內(nèi)
public void testFindThemeById() throws Exception {
}
@Test
public void testFindThemeReplys() throws Exception {
assertEquals(1,1);
assertThat(55, greaterThan(50));//判斷55是否大于50
}
}
再JUnit4中使用@Test
注解即可對(duì)任意函數(shù)簽名指定為測(cè)試函數(shù)陵且。然后JUnit4中還提供了@BeforeClass
來(lái)初始化一些昂貴的資源比如數(shù)據(jù)庫(kù)鏈接裁僧,使用@Before
來(lái)初始化準(zhǔn)備環(huán)境。BeforeClass
只會(huì)初始化一次慕购,但是@Before
每一次測(cè)試函數(shù)運(yùn)行之前都會(huì)運(yùn)行一次聊疲。同理AfterClass
和After
。
當(dāng)然JUnit4還有一些高級(jí)功能沪悲。比如參數(shù)化測(cè)試获洲,打包測(cè)試。有必要的話殿如,以后在列出例子贡珊。
除了JUnit4測(cè)試框架之外,還有模擬對(duì)象用的Mockito框架涉馁,Unitils框架门岔,數(shù)據(jù)庫(kù)測(cè)試框架Dbunit。
JUnit4有了Spring測(cè)試框架支持后的DAO測(cè)試
因?yàn)槭菍?duì)DAO層的測(cè)試烤送,所以要再Service層調(diào)用DAO層代碼進(jìn)行測(cè)試寒随。
沒(méi)有Spring測(cè)試框架之前
package service;
import static org.Junit.Assert.assertEquals;
import org.Junit.BeforeClass;
import org.Junit.Test;
import org.Springframework.context.ApplicationContext;
import org.Springframework.context.support.ClassPathXmlApplicationContext;
import domain.Account;
public class AccountServiceOldTest {
private static AccountService service;
@BeforeClass
public static void init() {
ApplicationContext
context = new ClassPathXmlApplicationContext("config/Spring-db-old.xml");
service = (AccountService)context.getBean("accountService");
}
@Test
public void testGetAcccountById() {
Account acct = Account.getAccount(1, "user01", 18, "M");
Account acct2 = null;
try {
service.insertIfNotExist(acct);
acct2 = service.getAccountById(1);
assertEquals(acct, acct2);
} catch (Exception ex) {
fail(ex.getMessage());
} finally {
service.removeAccount(acct);
}
}
}
有了Spring測(cè)試框架之后
package service;
import static org.Junit.Assert.assertEquals;
import org.Junit.Test;
import org.Junit.runner.RunWith;
import org.Springframework.beans.factory.annotation.Autowired;
import org.Springframework.test.context.ContextConfiguration;
import org.Springframework.test.context.Junit4.SpringJUnit4ClassRunner;
import org.Springframework.transaction.annotation.Transactional;
import domain.Account;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/config/Spring-db1.xml")
@Transactional
public class AccountServiceTest1 {
@Autowired
private AccountService service;
@Test
public void testGetAcccountById() {
Account acct = Account.getAccount(1, "user01", 18, "M");
service.insertIfNotExist(acct);
Account acct2 = service.getAccountById(1);
assertEquals(acct,acct2);
}
}
通過(guò)例子可以看出來(lái),Spring測(cè)試框架主要解決下面幾件事情帮坚。
- 不用手動(dòng)導(dǎo)入Spring的配置文件牢裳,可以使用注解進(jìn)行
- 不同手動(dòng)
getBean
得到Bean對(duì)象,Bean對(duì)象可以使用@Autowired
來(lái)進(jìn)行自動(dòng)注入 - 不用調(diào)用完DAO層代碼叶沛,然后撤銷(xiāo)操作影響,Spring測(cè)試框架直接事務(wù)回滾忘朝。
當(dāng)然為了使用到Spring測(cè)試框架的功能灰署,主要要使用到如下幾點(diǎn)的東西。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/config/Spring-db1.xml")
- 在Spring的配置文件中配置事務(wù)管理器
- @Transactional
JUnit有了Spring之后的Controller層測(cè)試(帶補(bǔ)充)
JUnit沒(méi)有Spring之前的測(cè)試
JUnit有了Spring之后的測(cè)試
以上是使用原始的Spring項(xiàng)目架構(gòu)的測(cè)試過(guò)程,但是如果使用了SpringBoot的話溉箕,還是會(huì)有一些不一樣的地方的晦墙。下面來(lái)講一下如果使用了SpringBoot的話,項(xiàng)目會(huì)又哪一些改變肴茄。