저작권 안내: 저작권자표시 Yes 상업적이용 No 컨텐츠변경 No

스프링5 입문

JSP 2.3

JPA 입문

DDD Start

인프런 객체 지향 입문 강의

'Groovy'에 해당되는 글 2건

  1. 2013.12.06 간단한 Spock 샘플
  2. 2013.12.05 Spock 2 환경 설정 하기(Eclipse 4.3 + Maven) (2)

기존에 Mockito와 JUnit Eclosed를 이용해서 작성한 테스트 코드를 Spock을 이용해서 재작성해봤다. 뭐랄까, 속이 다 후련하다. Spock이 좀 더 익숙해지면 여러 상황을 위한 테스트 코드 만드는데 도움이 될 것 같다.


class PaymentErpSyncSpockSpecification extends Specification {

    def PaymentErpSync sync = new PaymentErpSync()

    def PaymentSyncSourceDao mockSyncSourceDao = Mock()

    def PaymentInfoConverter mockPaymentInfoConverter = Mock();

    def ExternalErpClient mockExternalErpClient = Mock();

    def OrderSyncResultDao mockOrderSyncResultDao = Mock();


    def setup() {

        sync.setPaymentSyncSourceDao(mockSyncSourceDao)

        sync.setExternalErpClient(mockExternalErpClient)

        sync.setPaymentInfoConverter(mockPaymentInfoConverter)

        sync.setOrderSyncResultDao(mockOrderSyncResultDao)

    }

    

    def "PaymentSyncSourceDao 읽기 실패시"() {

        when: "동기화 실행"

        sync.syncPaymentInfo()

        

        then: "SyncSource 읽기 실패하고, 실패 결과 기록해야 함"

        mockSyncSourceDao.findAllByBeforeSync() >> { throw new RuntimeException() };

        mockOrderSyncResultDao.insert(_) >> { OrderSyncResult result ->

            assert result.result == false

            assert result.syncType == null

            assert result.failedSource == "PaymentSyncSourceDao"

        }

    }

    

    def "PaymentSyncSourceDao 읽기 성공시"() {

        setup: "PaymentSyncSourceDao 데이터 제공 설정"

        def paymentSyncSources =[

            PaymentSyncSource.builder().id(1L).saleDate(new Date()).type("p").build(),

            PaymentSyncSource.builder().id(2L).saleDate(new Date()).type("p").build()

        ]

        mockSyncSourceDao.findAllByBeforeSync() >> paymentSyncSources

        

        def paymentInfo = []

        paymentSyncSources.each { source ->

            mockPaymentInfoConverter.convert(source) >> paymentInfo

        }

        

        when: "동기화 실행하면,"

        sync.syncPaymentInfo()

        

        then: "ERP 전송 실패하고, 실패 결과 기록해야 함"

        2 * mockExternalErpClient.send(paymentInfo) >> { throw new SendFailureException() }

        2 * mockOrderSyncResultDao.insert({ OrderSyncResult result ->

            result.result == false &&

            result.syncType == SyncType.payment &&

            result.failedSource == "ExternalErpClient"

        })

        

        when: "동기화 실행하면,"

        sync.syncPaymentInfo()

        

        then: "모두 성공하고, 성공 결과 기록해야 함"

        2 * mockExternalErpClient.send(paymentInfo)

        2 * mockOrderSyncResultDao.insert({OrderSyncResult result ->

            result.result == true &&

            result.syncType == SyncType.payment

        })

    }

}



Posted by 최범균 madvirus

댓글을 달아 주세요

자바로 테스트 코드 만드는 게 좀 짜증이 나서 편하게 사용할만한 테스트 프레임워크를 뒤지다가 페이스북에서 Spock 이라는 놈을 줏어 들었다. 자바 기반의 프로젝트를 진행중인데, Spock가 그루비 기반이라서 궁합도 잘 맞을 것 같기에 일부 테스트 코드에서 넣어보기로 결심을 했다.


본격 사용하기에 앞서 개발 환경 구축은 필수! 아래의 순서로 진행을 했다.

  1. 이클립스에서 그루비 플러그인 설치
  2. pom.xml에 Spock 실행 위한 설정 추가
  3. src/test/groovy 폴더 생성
  4. Spock 테스트 코드 실행
그루비 플러그인 설치


http://groovy.codehaus.org/Eclipse+Plugin 사이트에 가면 이클립스 버전 별로 업데이트 사이트 주소를 확인할 수 있다. 필자는 이클립스 4.3 (Kepler) 버전을 사용중이서 http://dist.springsource.org/release/GRECLIPSE/e4.3/ 주소를 이용해서 플러그인을 설치했다. 메이븐 플러그인(m2e)와 연동을 해야 하므로, 메이븐 플러그인 커넥터도 함께 설치했다. (사실은 다 설치했다.)


그루비 플러그인을 설치한 다음에는 Windows > Preferences > Groovy > Compiler 에서 컴파일러 버전을 2.0 으로 변경한다. (변경하면 이클립스를 재시작한다.) 2.1이 아닌 2.0을 사용하는 이유는 Spock 0.7 버전이 현재 그루비 2.0 까지만 지원하기 때문이다.


pom.xml 파일 설정


메이븐 pom.xml 설정이 다소 복잡한데, 사용한 설정은 아래와 같다. Spock 0.7 버전은 현재 그루비 1.8 버전 또는 2.0 버전을 지원한다.


<project ...>

    <dependencies>

        ...

        <dependency>

            <groupId>org.spockframework</groupId>

            <artifactId>spock-core</artifactId>

            <version>0.7-groovy-2.0</version>

            <!-- 0.7-groovy-1.8 -->

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>org.codehaus.groovy</groupId>

            <artifactId>groovy-all</artifactId>

            <version>2.0.5</version>

            <scope>test</scope>

        </dependency>

    </dependencies>


    <build>

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>

                <version>3.1</version>

                <configuration>

                    <source>${java.version}</source>

                    <target>${java.version}</target>

                    <encoding>${project.build.sourceEncoding}</encoding>

                    <compilerId>groovy-eclipse-compiler</compilerId>

                </configuration>

                <dependencies>

                    <dependency>

                        <groupId>org.codehaus.groovy</groupId>

                        <artifactId>groovy-eclipse-compiler</artifactId>

                        <version>2.8.0-01</version>

                    </dependency>

                    <dependency>

                        <groupId>org.codehaus.groovy</groupId>

                        <artifactId>groovy-eclipse-batch</artifactId>

                        <version>2.0.7-03</version>

                        <!-- <version>1.8.6-01</version> -->

                    </dependency>

                </dependencies>

            </plugin>

        </plugins>

    </build>


</project>


테스트 목적으로만 쓸 거라서 groovy-all 의존의 범위를 test로 지정하였다.


주의사항:

  • spock 0.7 메이븐 의존은 Junit-dep 4.10 버전에 대한 의존을 갖는다. 따라서, Junit 4.11과 같이 다른 버전의 JUnit을 사용하고 있다면, JUnit 버전을 맞추기 위해 spock 의존 설정에 <exclustion>을 추가해서 junit-dep 의존을 제거한다.
  • groovy-all 용량이 커서, 최초 다운로드에 올래 걸리기도 한다. 메이븐 프로젝트 구성할 때에 인내심이 필요할 수 있다.

src/test/groovy 폴더 생성


그루비로 만든 테스트 코드를 넣기 위해 src/test 폴더 아래 groovy 폴더를 생성한다.


Spock 테스트 코드 실행


이제 남은 건 Spock 테스트 코드를 실행하는 것이다. src/test/groovy 폴더에 Spock 홈페이지에 있는 테스트 코드를 넣어본다. (HelloSpock.groovy)


import spock.lang.*


class HelloSpock extends spock.lang.Specification {

def "length of Spock's and his friends' names"() {

expect:

name.size() == length


where:

name     | length

"Spock"  | 5

"Kirk"   | 4

"Scotty" | 6

}

}


JUnit을 실행하는 것과 동일하게 "JUnit Run"으로 실행한다. 그러면, 아래와 같이 테스트가 통과하는 것을 확인할 수 있다.




Posted by 최범균 madvirus

댓글을 달아 주세요

  1. 미니양 2014.02.11 04:43 신고  댓글주소  수정/삭제  댓글쓰기

    Spock을 한번 따라해 보고 싶어서 작성해 주신 글대로 따라 해 봤습니다.
    Spock의 기본 샘플로 주신건 실행이 되는데,
    def MockSampleObj = Mock(SampleObj)
    이렇게 하면 MockSampleObj.someMethod를 하면 someMethod를 가져오지 못하고 밑줄이 그어지네요.

    혹시 원인을 알 수 있나요?