1.导入jar包:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
2.编写一个方法
在com.zzhblh.util包中创建一个类,类中有一个方法:
package com.zzhblh.util;
public class Math {
/**
* @param n
* @return
*/
public int add(int a, int b) throws Exception {
return a+b;
}
3.创建测试类,测试上面的方法:
接下来要对Math类进行单元测试。
创建一个和src同级别的文件夹叫test(逻辑代码放src里,测试代码放test里是个好习惯)。接着在IntelliJ IDEA里还要把这个test文件夹要设置成测试文件的根目录,右键选中Mark Directory As - Test Sources Root。
然后创建com.zzhblh.util.MathTest类(包名一致,类名在要测试的类名后加上Test也是个好习惯)。
package com.zzhblh.util;
import org.junit.Test;
import static org.junit.Assert.*;
public class MathTest {
@Test
public void testAdd() throws Exception {
assertEquals(11, new Math().add(5,6));
}
}
然后选中MathTest类ctrl + shift + F10运行一下,右下方一条绿色条说明测试通过,不通过显色红色条。
说明:
- 导入了org.junit.Test;和org.junit.Assert.*;这两个包,注意后者是静态导入import static(可以直接使用静态类中的方法,属性。不必写'类名.')。
- testAdd是在要测试的方法名add前加个test(这也是个好习惯)。
- 所有测试方法返回类型必须为void且无参数。
- 一个测试方法之所以是个测试方法是因为@Test这个注解。
- assertEquals的作用是判断两个参数是否相等。
- assertEquals除了比较两个int,还重载了好多次可以比较很多种类型的参数。而且JUnit4其他的assertXX方法。
几个常用的注解:
@Test:把一个方法标记为测试方法
@Before:每一个测试方法执行前自动调用一次
@After:每一个测试方法执行完自动调用一次
@BeforeClass:所有测试方法执行前执行一次,在测试类还没有实例化就已经被加载,所以用static修饰
@AfterClass:所有测试方法执行完执行一次,在测试类还没有实例化就已经被加载,所以用static修饰
@Ignore:暂不执行该测试方法
有测试类如下:
package com.zzhblh.util;
import org.junit.*;
import static org.junit.Assert.*;
public class AnnotationTest {
public AnnotationTest() {
System.out.println("构造方法");
}
@BeforeClass
public static void setUpBeforeClass() {
System.out.println("BeforeClass");
}
@AfterClass
public static void tearDownAfterClass() {
System.out.println("AfterClass");
}
@Before
public void setUp() {
System.out.println("Before");
}
@After
public void tearDown() {
System.out.println("After");
}
@Test
public void test1() {
System.out.println("test1");
}
@Test
public void test2() {
System.out.println("test2");
}
@Ignore
public void test3() {
System.out.println("test3");
}
}
运行结果如下:
BeforeClass
构造方法
Before
test1
After
构造方法
Before
test2
After
AfterClass
你会发现构造方法被执行了两次。因为JUnit4为了保证每个测试方法都是单元测试,是独立的互不影响。所以每个测试方法执行前都会重新实例化测试类。
可以把多个方法标记为@BeforeClass、@AfterClass、@Before、@After。他们都会在相应阶段被执行。
@Test注解中可以加上timeout属性,如@Test(timeout = 2000),单位为毫秒,表示说超出2秒将视为测试不通过。
4.自动生成测试类:
这里假设有更多方法需要测试,如果要一个一个写,太累了。IntelliJ IDEA可以自动生成测试方法的基本结构。按快捷键ctrl - shift - T。
弹出的对话框点击Create New Test...
5.结合Spring:
可以在Before方法中,初始化Spring容器
@Before
public void init() {
ApplicationContext ctx = new FileSystemXmlApplicationContext( "classpath:spring/spring-basic.xml");
baseDao = (IBaseDao) ctx.getBean("baseDao");
assertNotNull(baseDao);
}
但如上面提到的,每个测试方法执行前都会重新实例化测试类,这样导致容器被初始化多次。在测试Spring时我们可以使用Spring test。
导入jar包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version> 3.2.4.RELEASE </version>
<scope>provided</scope>
</dependency>
和上文一样,推荐创建一个和src平级的源文件目录test,而包的名称可以和src中的目录同名,这样由于在test源目录中,所以不会有冲突,而且名称又一模一样,也方便检索。
基类:
@RunWith(SpringJUnit4ClassRunner.class) //使用junit4进行测试
@ContextConfiguration({"/spring/app*.xml","/spring/service/app*.xml"}) //加载配置文件
//如果加入以下代码,所有继承该类的测试类都会遵循该配置,也可以不加,这个非常关键,如果不加入这个注解配置,事务控制就会失效
@Transactional
//这里的事务关联到配置文件中的事务控制器(transactionManager = "transactionManager"),同时//指定自动回滚(defaultRollback = true)。这样做操作的数据才不会污染数据库!
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class BaseJunit4Test {
}
自己的测试类:
public class UserAssignServiceTest extends BaseJunit4Test{
@Resource //自动注入,默认按名称
private IBaseDao baseDao;
@Test //标明是测试方法
@Transactional //标明此方法需使用事务
@Rollback(false) //标明使用完此方法后事务不回滚,true时为回滚
public void insert( ) {
String sql="insert into user(name,password) values(?,?)";
Object[] objs=new Object[]{"00","000"};
baseDao.insert( sql , objs );
String sql1="select * from user where name=? and password=? ";
List<Map<String,Object>> list=baseDao.queryForList( sql1 , objs );
System.out.println(list);
assertTrue(list.size( )>0);
}
}
@Rollback用于回滚数据库,能够完成功能逻辑检查,又能够在测试完成后恢复现场,不会留下“后遗症”。比如:用户在测试方法中插入一条ID为1的User记录,如果不回滚,第一次运行不会有问题,第二次运行时,就会因为主键冲突而导致测试用例失败。
要点:
所有测试方法返回类型必须为void且无参数。因为JUnit4为了保证每个测试方法互不影响,所以每个测试方法执行前都会重新实例化测试类,所以构造方法会执行多次。
几个常用的注解:
@Test:把一个方法标记为测试方法
@Before:每一个测试方法执行前自动都调用一次
@After:每一个测试方法执行完自动都调用一次
@BeforeClass:所有测试方法执行前执行一次,在测试类还没有实例化就已经被加载,所以用static修饰
@AfterClass:所有测试方法执行完执行一次,在测试类还没有实例化就已经被加载,所以用static修饰
测试Spring
导入spring-test包。
配置注解:
@RunWith(SpringJUnit4ClassRunner.class) //使用junit4进行测试
@ContextConfiguration({"/spring/app.xml","/spring/service/app.xml"}) //加载配置文件