Home JUNIT in egov
Post
Cancel

JUNIT in egov

JUNIT

  1. 테스트 코드 작업을 지원하는 라이브러리로 java 진영 뿐 아니라, xUnit 형태로 다른 언어도 지원
    • 이미지
    • 러너 - 테스트를 실행
    • 스위트 - 여러 테스트 클래스를 묶는 그룹
    • 테스트 클래스 - 여러 테스트를 포함한 클래스
  2. 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)사용 러너를 설정한다
@MockMock객체임을 선언
@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)사용 러너를 설정한다
@TestDataSourceDB 커넥션을 생성
@Transactional트랜젝션 오류 발생시, 정책설정 (위에서는 ROLLBACK)
@SpringApplicationContext설정 정보를 위치
@SpringBean([name])스프링의 빈 팩토리에서 대상 빈을 주입해준다.
  • 일반 dto를 사용하듯이 사용후, 검증하면 된다.

롤백 부분은 아직 추가 검증이 필요하다.

This post is licensed under CC BY 4.0 by the author.

Review

자바스터디 1주차

Comments powered by Disqus.

Trending Tags