이미 나온지 꽤 시간이 흐른 Junit 5를 살펴보기 시작한다.


[spring-boot] Junit5 적용기

JUnit5 의존성 추가

JUnit5가 세상에 모습을 드러내놓은지는 제법 됐다. 새로운 프로젝트를 시작하면서 JUnit5 와 Spock 을 기반으로 한 테스트를 작성하고자 한다.

스프링 부트 2에서 JUnit5 에 대한 의존성을 추가하고 테스트를 작성하는 방법을 설명한다.

buildscript {
    ext {
        springBootVersion = '2.0.6.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'io.honeymon.study'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 10

repositories {
    mavenCentral()
}

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('org.springframework.boot:spring-boot-starter-web')

    runtimeOnly('com.h2database:h2')
    compileOnly('org.projectlombok:lombok')

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude module: 'junit'
    }
    testImplementation('org.junit.jupiter:junit-jupiter-api:5.2.0')
    testCompile('org.junit.jupiter:junit-jupiter-params:5.2.0')
    testRuntime('org.junit.jupiter:junit-jupiter-engine:5.2.0')
}

test {
    useJUnitPlatform()
}

junit4 제외

스프링 부트 스타터 org.springframework.boot:spring-boot-starter-test는 junit4에 대한 의존성을 가지고 있다. 그래서 junit5를 사용하기 위해서는 spring-boot-starter-test에 추가되어 있는 junit4를 제외해야 한다.

testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude module: 'junit'
}
Note

그레이들에서 모듈에 대한 의존성 정의는 3개 부분으로 나뉜다.

  • 예: org.springframework.boot:spring-boot-starter-test

    • group: org.springframework.boot

    • module: spring-boot-starter-test

    • version: 생략

이런 구분을 이해하고 나면 위에서 설명한 제외(exclude)방법을 활용할 수 있을 것이다.

  • 그룹과 모듈을 정의하는 경우: exclude group: 'junit', module: 'junit' 으로 정의할 수 있다.

이어서 junit5에 대한 의존성을 추가한다.

dependencies {
    // 생략
    testImplementation('org.junit.jupiter:junit-jupiter-api:5.2.0')
    testCompile('org.junit.jupiter:junit-jupiter-params:5.2.0')
    testRuntime('org.junit.jupiter:junit-jupiter-engine:5.2.0')
    // 생략
}

이어서 test 태스크에서 useJUnitPlatform()를 선언한다. useJUnitPlatform는 테스트 실행시 JUnit 플랫폼(JUnit 5)이라는 것을 정의한다.

/**
 * Specifies that JUnit Platform (a.k.a. JUnit 5) should be used to execute the tests. <p> To configure JUnit platform specific options, see {@link #useJUnitPlatform(Action)}.
 *
 * @since 4.6
 */
@Incubating
public void useJUnitPlatform() {
    useJUnitPlatform(Actions.<JUnitPlatformOptions>doNothing());
}

이렇게 해서 build.gradle에서 JUnit5를 사용하기 위한 위존성 정리를 마쳤다.

테스트 작성

package io.honeymon.study.junit5;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)  // (1)
@SpringBootTest
public class SpringBoot2Junit5ApplicationTests {

    @Test // (2)
    public void contextLoads() {
    }

}
  1. ExtendWith는 JUnit5 에서 반복적으로 실행되는 클래스나 메서드에 선언한다. SpringExtension는 스프링 5에 추가된 JUnit 5의 주피터(Jupiter) 모델에서 스프링 테스트컨텍스트(TestContext)를 사용할 수 있도록 해준다.

  2. `@Test의 경로도 변경(org.junit.Testorg.junit.jupiter.api.Test)되었다.

이제 JUnit5를 기반으로 통합테스트를 위한 준비를 마쳤다.

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

Note

junit5는 람다를 기반으로 한 선언(assertion)을 지원한다. junit4에서 지원했던 기능이 부족하여 assertJ 의존성을 추가해야 했던 불편함을 해소할 수 있다.

증상

Java 8을 기본으로 개발을 해오고 있다. 그러다가 외부 교육을 할 기회가 있었는데, 이 때 교육생들은 대부분 윈도우즈를 사용하고 있었고, 나와는 다르게 오라클 Java Download 환경에서 11 혹은 10 버전을 설치운영하고 있었다.

Java 10 실행환경에서 스프링 부트 프로젝트를 실행하면 Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException 가 발생한다.

JAVA 9부터 빠진 기능들이 있다.

http://openjdk.java.net/jeps/320

  • java.xml.ws (JAX-WS, plus the related technologies SAAJ and Web Services Metadata)
  • java.xml.bind (JAXB)
  • java.activation (JAF)
  • java.xml.ws.annotation (Common Annotations)
  • java.corba (CORBA)
  • java.transaction (JTA)
대충 살펴보면 XML 과 관련된 모듈이 분리됐다.



해결방법

프로젝트 의존성 내에 compile "javax.xml.bind:jaxb-api" 을 추가한다.
스프링 부트에서는 의존성 관리기능을 통해 jaxb-api 버전을 관리하고 있기 때문에 굳이 버전을 신경쓰지 않아도 된다.



지난 2018/09/20 티아카데미에서 '스프링 부트로 웹 서비스 개발하기' 라는 짧은 강연에서 사용한 발표자료 3/3 번째 발표자료


지난 2018/09/20 티아카데미에서 '스프링 부트로 웹 서비스 개발하기' 라는 짧은 강연에서 사용한 발표자료 2/3 번째 발표자료


지난 2018/09/20 티아카데미에서 '스프링 부트로 웹 서비스 개발하기' 라는 짧은 강연에서 사용한 발표자료 1/3 번째 발표자료


+ Recent posts