Repository 테스트 코드를 작성하는데 마지막에 entityManager.flush를 해줘야지만 Query문이 보인다.
beforeTest에 DB에 직접 접근을 하면 Transaction 범위 내에서 사용하라고 말한다.
그런데 it이 여러개일 경우, 우선 beforeTest를 이뤄내기 위해서는 코드 중복이 많이 일어날 것이다.
또한 실수로라도 마지막 줄에 flush가 없다면 query문이 보이지 않기 때문에 적어줘야 한다는 점이 매우 마음에 들지 않았다.
실수의 여지도 있으며, 보기에 썩 좋아보이지는 않았다.
말 그대로이다.
함수형 언어이므로 함수를 한번 더 감싸게 만들 수만 있다면 가능하다고 판단을 하고 시도를 해보았다.
typealias BeforeTest = () -> Unit
suspend fun DescribeSpecContainerScope.flushIt(
name: String,
em: TestEntityManager,
beforeTest: BeforeTest? = null,
test: suspend TestScope.() -> Unit
) {
this.it(name) {
beforeTest?.invoke()
test.invoke(this)
em.flush()
}
}
describe(){
context(){
val beforeTest: BeforeTest = { doSomething... }
flushIt("", entityManager, beforeTest){
}
}
}
entityManager를 주입을 필수로 해줘야하며, beforeTest의 경우 선택사항으로 두도록 만들었다.
결과적으로 it 내부에 있는 코드는 spec상의 요구와 맞게끔 작성할 수 있게 되었다.
사실, 문제는 test마다 beforeTest가 돌아가기 때문에 context로 그것을 확장 시키고 싶지만 context에서는 transaction에서 벗어나있고, it에 주입할만한 방법이 떠오르지가 않는다.