在工作完成后,都需要对代码进行测试用例编写,如果采用TDD,那就更加离不开测试。
JUnit
添加Maven依赖
1 2 3 4 5 6
| <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
|
- 添加scope为test,表面该依赖只是在测试的时候使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class DemoService { public boolean demo(List<String> str) { return str.add("whh"); } }
public class DemoServiceTest { @Test public void demo() throws Exception { List<String> list = new ArrayList<>(); list.add("whh"); list.add("whhxz"); System.out.println(list); } }
|
创建测试类,如上。
上述代码是通过IntelliJ IDEA生成测试类,为了规范,一般为需要测试的类后加上Test
。通常会在测试代码中加上断言,IDEA在运行测试时,会自动加上-ea
参数,断言失败时就会抛出异常。其他复杂方式可查看官方文档。
Junit核心在于org.junit.runner.JUnitCore
。可以通过打印方法调用栈堆来分析。
SpringJunit
通常在项目中使用Spring框架,对代码进行测试时可以使用spring-test
。
添加maven依赖
1 2 3 4 5 6
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.13.RELEASE</version> <scope>test</scope> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12
| @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath*:applicationContext.xml") public class TimeReplenishTaskServiceTest { @Autowired @Qualifier("timeReplenishTaskService") private AbstractReplenishTask replenishTask;
@Test public void create(){ replenishTask.doSomethind(); } }
|
如上使用SpringTest,通过RunWith
配置SpringJUnit4ClassRunner
,指定由SpringJUnit4ClassRunner
启动,ContextConfiguration
用来配置环境,其他的注入就如同普通的Spring注入。
Junit允许通过RunWith
改变默认的执行类,不然默认就是org.junit.runners.Suite
。
TestNG
添加maven依赖
1 2 3 4 5 6
| <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.8</version> <scope>test</scope> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class DemoServiceTest {
@org.testng.annotations.Test public void demo() throws Exception { System.out.println("demo"); }
@org.testng.annotations.Test public void login() throws Exception { int i = 1 / 0; }
@org.testng.annotations.Test(dependsOnMethods = {"login"}) public void userInfo() throws Exception { System.out.println("userInfo"); } }
|
如上TestNG使用看起来和Junit一样,在TestNG中可以使用更多的功能,比如依赖。如上,userInfo就依赖于login测试,如果login失败,后续的userInfo就会直接跳过。
同时TestNG可以通过写xml文件来进行组合测试。
1 2 3 4 5 6 7 8
| <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="Suite" thread-count="5" verbose="1" parallel="false"> <test name="demoService"> <classes> <class name="com.whh.netty.DemoServiceTest"/> </classes> </test> </suite>
|
在xml中可以配置多个测试类进行整个流程的测试。
TestNG结合spring
1 2 3 4 5 6 7 8 9 10 11 12
| @org.testng.annotations.Test @ContextConfiguration(locations = "classpath*:applicationContext.xml") public class TimeReplenishTaskServiceTest extends AbstractTestNGSpringContextTests { @Autowired @Qualifier("timeReplenishTaskService") private AbstractReplenishTask replenishTask;
@org.testng.annotations.Test public void create(){ replenishTask.doSomethind(); } }
|
通过继承AbstractTestNGSpringContextTests来实现和Spring结合使用。
参考:JUnit 4 与 TestNG 的对比
Mock框架
在开发过程中,可以依赖的某个功能未开发完成,就可以通过Mock框架来模拟对象替换部分功能来完成。
mockito
简单使用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class DemoServiceTest { @Test public void demo() { List list = Mockito.mock(List.class); Mockito.when(list.get(0)).thenReturn("whh"); String result = (String) list.get(0); Mockito.verify(list).get(0); Assert.assertEquals("whh", result);
} }
|
使用的Junit做的测试。创建mock对象不能对final,Anonymous,primitive类进行mock。
同时还可以设置方法返回异常等操作。
其他操作查看:
mockito github
mockito官网
同样的mock框架还有jmockit、easymock
未完待续。。。