저의 원래 목적은 @BeforeAll로 미리 원하는 데이터에 대해 셋팅하고 나머지 테스트를 진행하는 것이였습니다.
그래서 @BeforeAll을 사용했습니다.

하지만 @BeforeAll은 반드시 static으로 선언되어야 한다고 합니다. 한가지 의문이 있었습니다. 왜 굳이 static으로 할까?
우선은 그냥 static을 사용하기로 했습니다.
그래서 static을 사용하니


위와 같이 의존성이 제대로 주입되지 않는 상황이 발생했습니다. 분명 @BeforeAll을 사용하기 전에는 문제가 없었는데 말이죠.
사실 왜 안되는 지는 간단합니다.
static은 class가 메모리에 할당됐을 때 메모리에 할당됩니다. 또한 의존성을 주입하기 위해선 인스턴스가 생성되어야 주입이 가능합니다.
즉 class가 메모리에 올라가 static 변수를 할당하고자 하는데 다른 Bean의 인스턴스가 생성되지 않는 상황이니 주입받지 못하는 상황인 것이죠.
그래서 static을 통한 @BeforeAll은 제가 원하는 방향으로는 사용 불가능 합니다.
그렇다면 BeforeAll을 static이 아닌 일반 메서드로 사용하고자 한다면 어떻게 하면 될까요?
per-class를 사용해서 해결합니다.
junit의 테스트 실행 방법은 다음과 같습니다.
junit 공식문서 TestInstanse를 참고하면
https://junit.org/junit5/docs/5.0.0/user-guide/#writing-tests-annotations
junit은 per-method 방식으로 진행되는 것을 확인할 수 있습니다.
per-method는 테스트 메서드가 실행되기 전 인스턴스를 새롭게 만들어 테스트를 진행하는 방식입니다. 즉 테스트가 3개라면 테스트가 진행되는 동안 3개의 인스턴스가 만들어지는 것이죠.
이렇게 하면 얻는 이점은 안정성입니다. 변경 가능한 테스트 인스턴스의 영향으로 테스트가 제대로 진행되지 않는 것을 방지하고자 per-method 방식을 기본적으로 junit에서 사용합니다.
자 그럼 위에서 제가 언급한 굳이 @BeforeAll을 static으로 사용해야할까? 라는 의문이 해결됩니다.
테스트 마다 인스턴스가 생성되기에 이에 상관없이 @BeforeAll을 사용할려면 당연하게도 static으로 생성하는 것이 맞습니다.
이러한 per-method 방식은 per-class 방식으로 변경 가능합니다.
per-method가 테스트(method)가 실행되기 전 인스턴스를 생성한다면 per-class는 class가 생성되면 인스턴스를 만드는 방식입니다. 즉 테스트 진행 시 하나의 인스턴스만 만들어지는 방식입니다.
그렇다면 인스턴스가 하나만 만들어지니 굳이 static을 사용하지 않아도 됩니다.
그럼 이제 per-class 방식으로 바꾸고 실행해봅시다.
per-class는 TestInstance를 불러와 아래와 같이 설정해주면 됩니다.

@BeforeAll
void beforeAll(){
uid = UUID.randomUUID();
category1 = Category.builder()
.user_id(uid)
.category_name("test category1")
.build();
category2 = Category.builder()
.user_id(uid)
.category_name("test category2")
.build();
method1 = Method.builder()
.user_id(uid)
.method_name("test method1")
.build();
method2 = Method.builder()
.user_id(uid)
.method_name("test method2")
.build();
Category c1 = categoryRepository.save(category1);
cid1 = c1.getId();
Category c2 = categoryRepository.save(category2);
cid2 = c2.getId();
Method m1 = methodRepository.save(method1);
mid1 = m1.getId();
Method m2 = methodRepository.save(method2);
mid2 = m2.getId();
}
그럼 실행해봅시다.

위와 같은 에러가 발생합니다.
Entity manager가 현재 스레드 상에서 사용할 수 없습니다.(?)
EntityManager는 영속성 컨텍스트에 접근하기 위해 사용합니다. 근데 사용할 수 없다고 합니다.
No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
Transaction과 연결된 EntityManager가 현재 쓰레드 내에 없다고 합니다.

분명 DataJpaTest에 @Transational이 존재해서 Transaction이 적용되어 있다고 생각했지만 그렇지 않아 보입니다.
그래서 구글링하다가 마지막엔 공식문서를 뒤적여봤습니다.
https://docs.spring.io/spring-framework/reference/testing/testcontext-framework/tx.html

정확히 나와 있습니다... @BeforeAll은 테스트 관리 트랜잭션 내에서 실행 되지 않는다고 합니다.
즉 Transaction과 연결된 EntityManager가 필요한데 저는 EntityManager를 Transaction이 사용되지 않는 @BeforeAll에서 사용했기 때문에 위와 같은 문제가 발생한 것이죠.
그래서 결국 저는 @BeforeEach를 사용했습니다.
@BeforeEach
void beforeEach(){
uid = UUID.randomUUID();
category1 = Category.builder()
.user_id(uid)
.category_name("test category1")
.build();
category2 = Category.builder()
.user_id(uid)
.category_name("test category2")
.build();
method1 = Method.builder()
.user_id(uid)
.method_name("test method1")
.build();
method2 = Method.builder()
.user_id(uid)
.method_name("test method2")
.build();
Category c1 = categoryRepository.save(category1);
cid1 = c1.getId();
Category c2 = categoryRepository.save(category2);
cid2 = c2.getId();
Method m1 = methodRepository.save(method1);
mid1 = m1.getId();
Method m2 = methodRepository.save(method2);
mid2 = m2.getId();
}
그렇다면 드디어! 아무런 문제없이 테스트가 진행됩니다...
사실 BeforeAll에 집착했던 이유는 단 하나입니다. 말 그대로 모든 테스트 전에 모든 데이터에 대한 셋팅을 해주고 싶었습니다.
그러나 모든 블로그에서는 @BeforeAll이 아닌 @BeforeEach를 사용했고 굳이 이래야하나? 라는 생각에 깊게 매몰되었던 것 같습니다.
junit의 동작을 이해하고 보니 @BeforeEach를 사용하는 것도 이름의 의미 상 문제는 없다고 생각하고 나니 마음이 한결 편해졌습니다.
진작에 공부를 많이 하고 진행했으면 상관없었을텐데...