Archive for category unit test
เขียน test งานขำ ๆ กับ Spring + jUnit4
Posted by boysbee in java, junit, programming, spring framework, unit test on 10/06/2011
เรื่องมันมีอยู่ว่า..เดิมเป็นคนเขียนงานไม่ค่อยเขียน test ก็ด้นสดกันไป เขียน test แบบไหนนะหรอ? ก็เขียนใน main method ไง แทรกไว้ใน class นั้นละ แบบนี้
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
private static int YEAR = 3000;
private static int MONTH = 12;
private static int DATE = 31;
private static int HOUR = 24;
private static int MINUTE = 60;
private static int SECOND = 60;
public static void test() {
int time[][][] = new int[HOUR][MINUTE][SECOND];
for (int i = 0; i < time.length; i++) {
for (int j = 0; j < time[i].length; j++) {
for (int k = 0; k < time[i][j].length; k++) {
// System.out.println(i + " : " + j + " : " + k);
time[i][j][k] = 0;
}
}
}
int counter = 0;
System.out.println("time 1:00:00 : " + time[1][0][0]);
// set time 1:30:20 to counter 1
time[1][30][20] += 1;
time[1][30][20] += 1;
time[1][31][20] += 1;
// count between time 1:30:00 - 1:30:59
for (int i = 0; i < time[1][30].length; i++) {
counter += time[1][30][i];
}
System.out.println("count between time 1:31:00 - 1:30:59 : " + counter);
// count between time 1:31:00 - 1:31:59
counter = 0;
for (int i = 0; i < time[1][31].length; i++) {
counter += time[1][31][i];
}
System.out.println("count between time 1:31:00 - 1:31:59 : " + counter);
// time 1:00:00
time[1][0][0] += 1;
// time 1:03:24
time[1][3][24] += 1;
// time 2:00:23
time[2][0][23] += 1;
// count between time 1:00:00 - 3:00:00
counter = 0;
for (int i = 0; i < SECOND; i++) {
for (int j = 0; j < MINUTE; j++) {
for (int h = 1; h <= 3; h++) {
counter += time[h][j][i];
}
}
}
System.out.println("count between time 1:00:00 - 3:00:00 : " + counter);
}
}
ผลที่ได้นะหรอ ก็รันได้ราบรื่นปรกตินะซิแล้วไปตายเอาดาบหน้า
หลังจากได้อ่าน Test Driven Development ที่พี่ roofimon เขียนไว้ หลัง ๆ เลยเปลี่ยนตัวเองใหม่สาบานว่าจะเขียน 1 test class ต่อ class ที่เขียนขึ้นหนึ่งตัว ( กรณีขยันสุด ๆ นะ ) ผลที่ได้นะหรอเขียนตั้งแต่ test domain class ยัน test service class กันเลยทีเดียว เดี๋ยวจะหาว่าโม้ ขั้นตอนเขียน JUnit4 ( ใช้ version 4 มันง่ายเพราะมี annotation ) เขียนยังงี้ครับ
import junit.framework.Assert;
import org.junit.Test;
public class TestEventDomain {
private static int YEAR = 3000;
private static int MONTH = 12;
private static int DATE = 31;
private static int HOUR = 24;
private static int MINUTE = 60;
private static int SECOND = 60;
@Test
public void testHour() {
int time[][][] = new int[HOUR][MINUTE][SECOND];
for (int i = 0; i < time.length; i++) {
for (int j = 0; j < time[i].length; j++) {
for (int k = 0; k < time[i][j].length; k++) {
// System.out.println(i + " : " + j + " : " + k);
time[i][j][k] = 0;
}
}
}
int counter = 0;
int m = 0;
System.out.println("time 1:00:00 : " + time[1][0][0]);
// set time 1:30:20 to counter 1
time[1][30][20] += 1;
time[1][30][20] += 1;
time[1][31][20] += 1;
Assert.assertEquals(2, time[1][30][20]);
Assert.assertEquals(1, time[1][31][20]);
// // count between time 1:30:00 - 1:30:59
for (int i = 0; i < time[1][30].length; i++) {
counter += time[1][30][i];
}
Assert.assertEquals(2, counter);
System.out.println("count between time 1:31:00 - 1:30:59 : " + counter);
// // count between time 1:31:00 - 1:31:59
counter = 0;
for (int i = 0; i < time[1][31].length; i++) {
counter += time[1][31][i];
}
Assert.assertEquals(1, counter);
System.out.println("count between time 1:31:00 - 1:31:59 : " + counter);
// time 1:00:00
time[1][0][0] += 1;
// time 1:03:24
time[1][3][24] += 1;
// time 2:00:23
time[2][0][23] += 1;
// count between time 1:00:00 - 3:00:00
counter = 0;
for (int i = 0; i < SECOND; i++) {
for (int j = 0; j < MINUTE; j++) {
for (int h = 1; h <= 3; h++) {
counter += time[h][j][i];
}
}
}
Assert.assertEquals(6, counter);
System.out.println("count between time 1:00:00 - 3:00:00 : " + counter);
}
}
แค่ประกาศบนหัวเป็น annotation @Test ครับแล้วรันแบบ JUnit Test บน eclipse มันก็รันแล้วรอดูผลบน console ได้ปกติ แล้วมันเอามาใช้กับ spring ยังไงละ ปกติถ้าเราเขียน spring แบบ basic เราจะมี configulation ที่เป็น file xml หนึ่งตัวใช่ไหมละ ดัง code ข้างล่างนี้ราจะเรียกมันผ่าน main method โดย new ClassPathXmlApplicationContext แล้วเราก็ใส่ file configulation นั้นลงไปเราจะได้ instance ของ application context มาเพื่อจะเรียก bean แล้วดำเนินการต่อไป
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.my.scheduler.quartz.service.JobService;
public class SpringTest {
private static ApplicationContext ctx;
public static void main(String[] args) {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
JobService readFileJobService = (JobService) ctx.getBean("readFileJobService");
try {
readFileJobService.doJob();
} catch (Exception e) {
e.printStackTrace();
}
}
}
ที่นี่ถ้าจะเขียนเพื่อดึง bean จาก spring มา test แบบ junit ทำยังไง? spring เตรียมมาให้แล้วครับด้วย class SpringJUnit4ClassRunner อยู่ใน package org.springframework.test.context.junit4 วิธีการก็ง่าย ๆ ใช้ annotation @RunWith กับ @ContextConfiguration และ @Resource ช่วยเข้าไปเท่านี้เรียบร้อยดังตัวอย่าง
import java.io.FileNotFoundException;
import javax.annotation.Resource;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.my.scheduler.quartz.service.JobService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath*:/applicationContext-common-hibernate.xml",
"classpath*:/applicationContext-log-aop.xml",
"classpath*:/applicationContext-dao.xml",
"classpath*:/applicationContext-aop.xml",
"classpath*:/applicationContext-job.xml" })
public class ReadFileJobWorkerImplTest {
@Resource(name = "readFileJobService")
JobService readFileJobService;
@Test
public void loadTest() {
try {
readFileJobService.doJob();
} catch (NullPointerException e) {
// if some path is null or empty can except null pointer exception
Assert.assertEquals(true, (e instanceof NullPointerException));
} catch (FileNotFoundException e) {
Assert.assertEquals(true, (e instanceof FileNotFoundException));
} catch (Exception e) {
e.printStackTrace();
}
}
}
ลองเอาไปเล่นกันดูครับ