JUNIT
- 테스트 코드 작업을 지원하는 라이브러리로 java 진영 뿐 아니라, xUnit 형태로 다른 언어도 지원
- 러너 - 테스트를 실행
- 스위트 - 여러 테스트 클래스를 묶는 그룹
- 테스트 클래스 - 여러 테스트를 포함한 클래스
- Mock
- not real but appearing or pretending to be exactly like something
- 진짜처럼 모습을 가장하는 것
- 테스트에서는 구현하기 힘들거나, 어려운 객체를 가장하는 객체를 의미
- 이러한 기능은 지원하는 라이브러리는 여러가지가 있으나, 아래에서는 eazymock이라는 라이브러리를 이용
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.4.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.unitils</groupId>
<artifactId>unitils</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
테스트에서만 사용하기 위해,
속성을 test로 설정
서비스 레이어 테스트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package egovframework.com.org.onnara.service.impl;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.unitils.UnitilsJUnit4TestClassRunner;
import org.unitils.easymock.EasyMockUnitils;
import org.unitils.easymock.annotation.Mock;
import org.unitils.inject.annotation.InjectIntoByType;
import org.unitils.inject.annotation.TestedObject;
import egovframework.com.cmm.EgovMessageSource;
import egovframework.com.org.syn.service.EgovOrgnztSync;
import egovframework.com.org.syn.service.impl.EgovOrgnztSyncServiceImpl;
import egovframework.rte.fdl.property.EgovPropertyService;
@RunWith(UnitilsJUnit4TestClassRunner.class)
public class OnnaraUserMngServiceImplTestByBase {
@Mock
@InjectIntoByType
protected EgovPropertyService propertyService;
@Mock
@TestedObject
private EgovOrgnztSyncServiceImpl syncService;
@Before
public void setup(){
syncService = new EgovOrgnztSyncServiceImpl();
}
@Test
/**
* baseUserInfoSetting
* @throws Exception
*/
public void 기본정보_미존재시_기본값_설정처리_확인() throws Exception {
//녹화
expect(propertyService.getString("Globals.orgSyncUserDefaultEamilAdres")).andReturn("test");
expect(propertyService.getString("Globals.orgSyncUserDefaultOffmTelno")).andReturn("test");
expect(propertyService.getString("Globals.orgSyncUserDefaultFxnum")).andReturn("test");
expect(propertyService.getString("Globals.orgSyncUserDefaultOrgnztZip")).andReturn("test");
expect(propertyService.getString("Globals.orgSyncUserDefaultOrgnztAdres")).andReturn("test");
expect(propertyService.getString("Globals.orgSyncUserDefaultOrgnztAdres2")).andReturn("test");
//재생
EasyMockUnitils.replay();
EgovOrgnztSync testegovOrgnztSync = new EgovOrgnztSync();
syncService.baseUserInfoSetting(testegovOrgnztSync);
//검증
verify(propertyService);
assertEquals("이메일정보", "test", testegovOrgnztSync.getEmailAdres());
assertEquals("부서연락처", "test", testegovOrgnztSync.getOrgnztTelno());
assertEquals("부서팩스", "test", testegovOrgnztSync.getOrgnztFaxno());
assertEquals("우편번호", "test", testegovOrgnztSync.getOrgnztZip());
assertEquals("주소", "test", testegovOrgnztSync.getOrgnztAdres());
assertEquals("주소2", "test", testegovOrgnztSync.getOrgnztAdres2());
}
}
대상 | 설명 |
---|---|
@RunWith(UnitilsJUnit4TestClassRunner.class) | 사용 러너를 설정한다 |
@Mock | Mock객체임을 선언 |
@InjectIntoByType | 테스트될 서비스에 주입되는 의존성을 설정해준다. unitils에서 지원하는 기능 |
@TestedObject | 테스트 대상 서비스를 선언 |
@Before | 매 테스트가 실행시, 초기화 시켜줄 method에 붙인다. |
@Test | 테스트 메소드에 붙인다. |
assert* | 단언문으로 해당 테스트를 검증 가능하다. 위에서는 assertEquals를 사용하여 검증을 진행 |
easyMock
easyMock의 프로세스 흐흠은 [녹화 > 재생 > 검증 ]으로, 진행된다.
- 녹화
- 테스트하기위한 프로세스를 설정하는 단계로, 기대되는 프로세스를 미리 지정하여 검증이 가능하도록 할 수 있다.
- expect([method]).andReturn([value]) // 구현중이거나, 외부 API를 테스트하기위해, 특정 method를 호출시 반환값을 설정한다.
- 재생
- 녹화된 프로세스를 재생하는 기능
- 반드시 재생 후, 테스트 대상 메소드를 실행
- 검증
- verify([target]) 으로 녹화된 프로세스 테스트
Unitls
eazymock의 부족한 기능을 보완하는 라이브러리
- 실 서비스에서 의존성을 주입받는 구현체를 적절하게 주입해준다
DTO 레이어 테스트
DB 테스트를 위해서는 DB 접속 정보, 타입등의 정보를 미리 설정해 주어야 한다. unitils에서 제공하는 기능을 통해 간단하게 설정 가능.
[projectName]/src/test/resources/unitils.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Properties for the PropertiesDataSourceFactory
# PropertiesDataSourceFactory 설정
database.driverClassName=oracle.jdbc.driver.OracleDriver
database.url=jdbc:oracle:thin:@192.168.200.225:1521:sfep
database.userName=seogu
database.password=sfseogu
# 테스트시 적용한 트렌젝션 처리를 설정, 지원하는 설정값은 'disabled', 'commit', 'rollback'.
# disabled 사용시, 트렌젝션 처리를 하지 않는다.
# commit 사용시, commit 처리를 진행 한다.
# rollback 사용시, 매 테스트 마다 rollback 처리를 진행한다
DatabaseModule.Transactional.value.default=rollback
# DataSet, ExpectedDataSet 사용을 위한 dms 정보 설정 ( 'oracle', 'db2', 'mysql', 'hsqldb', 'postgresql' )
database.dialect=oracle
# 스키마 이름 설정
database.schemaNames=SEOGU
# 트랜잭션 매니저 설정 ( 'auto', 'spring', 'simple' )
transactionManager.type=auto
# 테이블 자동 생성 등의 스키마 관리 기능 사용 여부 및 DML 위치 설정
#updateDataBaseSchema.enabled=true
#dbMaintainer.script.locations=src/test/resources/META-INF/persistence/maintenance/oracle
#dbMaintainer.disableConstraints.enabled=true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package egovframework.com.org.syn.service.impl;
import static org.junit.Assert.*;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.unitils.UnitilsJUnit4TestClassRunner;
import org.unitils.database.annotations.TestDataSource;
import org.unitils.database.annotations.Transactional;
import org.unitils.database.util.TransactionMode;
import org.unitils.spring.annotation.SpringApplicationContext;
import org.unitils.spring.annotation.SpringBean;
import egovframework.com.cmm.ComDefaultVO;
import egovframework.com.org.syn.service.EgovOrgnztSync;
@RunWith(UnitilsJUnit4TestClassRunner.class)
@Transactional(TransactionMode.ROLLBACK)
@SpringApplicationContext({
"/spring/*.xml",
"/egovframework/sqlmap/*.xml",
})
public class EgovOrgnztSyncDaoTest{
/**
* unitils.properties 에 설정 된 database 접근 정보를 기반으로
* 테스트 용 DataSource 를 만든 후 자동으로 injection 해 준다.
* (unitils.properties 파일의 위치와 이름은 변경할 수 없다.)
*
* updateDataBaseSchema.enabled=true 로 설정되어 있으면
* dbMaintainer.script.locations 에서 지정한 위치의 sql 문을 실행시켜준다.
* 주의) 생성 시점은 test 메소드가 실행되기 전이다.
* 따라서, 단순히 TestDataSource 만 선언하는 것이 아니라,
* 하나 이상의 test 메소드라도 있어야 결과 확인이 가능하다.
*
* @see unitils.properties
* @see dbMaintainer.script.locations 에서 지정한 위치의 sql 문
*/
@TestDataSource
private DataSource dataSource;
/** 테스트를 위해 만든 타겟 클래스로서 공지사항 비즈니스 구현을 위한 Dao */
@SpringBean("egovOrgnztSyncDao") //위의 설정에서 의존성을 전부 주입해주지 않으면, spring bean 생성 오류가 발생
EgovOrgnztSyncDao dao = new EgovOrgnztSyncDao();
@Test
public void DB_연결확인(){
assertNotNull("DB 연결 확인",dataSource);
}
@Test
public void testSelectDeptSyncCnt() throws Exception {
ComDefaultVO vo = new ComDefaultVO();
int result = dao.selectDeptSyncCnt(vo);
assertEquals("조회 건수", 0 , result);
}
/**
* 사용자싱크 한건(USER_WORKER테이블 --> COMTNEMPLYRINFO테이블로 적용)
* @throws Exception
*/
@Test
public void 사용자_신규_등록() throws Exception {
String userId = "test";
String syncNo = "1";
EgovOrgnztSync syncResult = dao.userSyncProc(userId, syncNo);
assertEquals("신규등록성공", "Y",syncResult.getInResult());
}
// 동기화 이력 저장
@Test
public void testUserSyncResultUpdate() throws Exception {
EgovOrgnztSync selectUserSync = new EgovOrgnztSync();
selectUserSync.setSyncNo("1");
selectUserSync.setUserId("test");
selectUserSync.setInResult("Y");
dao.userSyncResultUpdate(selectUserSync);
}
}
대상 | 설명 |
---|---|
@RunWith(UnitilsJUnit4TestClassRunner.class) | 사용 러너를 설정한다 |
@TestDataSource | DB 커넥션을 생성 |
@Transactional | 트랜젝션 오류 발생시, 정책설정 (위에서는 ROLLBACK) |
@SpringApplicationContext | 설정 정보를 위치 |
@SpringBean([name]) | 스프링의 빈 팩토리에서 대상 빈을 주입해준다. |
- 일반 dto를 사용하듯이 사용후, 검증하면 된다.
롤백 부분은 아직 추가 검증이 필요하다.
Comments powered by Disqus.