이전 포스팅에서 Play 2.1에 Slick을 연동하는 방법을 설명했는데 이때 작성한 테스트 코드를 다시 보자.
package models
import org.scalatest.FunSpec
import org.scalatest.matchers.ShouldMatchers
import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession
class UserSpec extends FunSpec with ShouldMatchers {
describe("example") {
it("사용자를 추가하고 조회한다") {
Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession {
// given
Users.ddl.create
Users.add(new User("outsider", "Outsider", "example@gamil.com"))
// when
val results = Users.findAll
// then
results.size should equal(1)
}
}
it("사용자를 추가하고 조회한다 2") {
Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession {
// given
Users.ddl.create
Users.add(new User("outsider", "Outsider", "example@gamil.com"))
// when
val results = Users.findAll
// then
results.size should equal(1)
}
}
}
}
테스트를 하나 더 추가했는데 여기서 보듯이 Slick을 돌리기 위해서 Session
이 필요하기 때문에 디비 설정을 위한 세션을 유닛테스트마다 추가해 주어야 한다. 즉, 다음과 같은 코드를 모든 유닛테스트마다 추가해 주어야 한다.
Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession {
Users.ddl.create
}
보통 하나의 스펙에서는 같은 디비설정을 사용할 것이고 DDL 정의도 동일할 것이므로 이는 상당한 중복을 발생시키고 불필요한 중복코드로 테스트코드를 읽는데도 방해가 된다. 이 문제를 어떻게 해결해야 할지 알 수 없어서 스택오버플로우에 질문 올렸더니 Slick의 메인개발자인 Stefan Zeiger가 직접 대답을 해주었다. 덕분에 유닛테스트를 다음과 같이 수정할 수 있다.
package models
import org.scalatest.{BeforeAndAfter, FunSpec}
import org.scalatest.matchers.ShouldMatchers
import scala.slick.driver.H2Driver.simple._
class UserSpec extends FunSpec with BeforeAndAfter with ShouldMatchers {
implicit var session: Session = _
before {
session = Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver").createSession()
Users.ddl.create
}
after {
session.close()
}
describe("example") {
it("사용자를 추가하고 조회한다") {
// given
Users.add(new User("outsider", "Outsider", "example@gamil.com"))
// when
val results = Users.findAll
// then
results.size should equal(1)
}
it("사용자를 추가하고 조회한다 2") {
// given
Users.add(new User("outsider", "Outsider", "example@gamil.com"))
// when
val results = Users.findAll
// then
results.size should equal(1)
}
}
}
일단 임포트문에서 threadLocalSession
을 제거해주고 유닛테스트 앞뒤로 실행할 before
와 after
를 사용하기 위해서 ScalaTest의 BeforeAndAfter
트레이트를 믹스인한다. 테스트에서 사용할 Session
변수를 선언하고 before
에서 세션을 생성하고 DDL 문을 생성하고 after
에서 세션을 닫아준다. 이렇게 작성하면 각 유닛테스트에는 테스트에 필요한 코드만 넣을 수 있고 마찬가지로 각 테스트는 독립적인 세션하에서 실행할 수 있다.
Comments