테스트 코드 작성을 하며 모든 클래스의 상단에 annotation이 반복되는 것을 목격할 수 있었다.
뭐 한두개면 와 다음에도 적자~ 하겠지만 매번 annotation을 5개씩 적어야한다면 끔찍하군.
이를 방지하고자 annotation을 만들어 관리하려고 한다.
물론, Thanks to Igoc. 덕분에 이런걸 알았어.
간단히 예를 들어, Repository test의 경우 아래와 같이 @DataJpaTest와 @AutoConfigureTestDatabase에 관련된 어노테이션이 필요하고 이를 하나의 annotation인 @RepositoryTest 하나로 만들고 싶은 것이다.
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class RepositoryIntegrationTest {
...
}
------------------------------------
@RepositoryIntegrationTest
class RepositoryIntegrationTest {
...
}
@interface로 annotation임을 알려준다.
public @interface Annotation {
...
}
필요한 annotation을 작성한다.
@annotation1
@annotation2
public @interface Annotation {
...
}
annotation 위에 아래의 annotation 2개를 필수적으로 추가한다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
------------------------------------
@annotation1
@annotation2
public @interface Annotation {
...
}
@Target : 선언한 annotation이 적용될 수 있는 위치를 결정한다.
@Retention : annotation이 어느 레벨까지 유지되는지를 결정짓는다.
@Inherited : 자식클래스가 어노테이션을 상속받는다.
@Documented : 해당 annotation이 자바 문서 생성시 자바 문서에도 포함시킨다.
@Repeatable : 반복 선언을 가능하게 만들어준다.
아래는 Igoc의 코드 중 일부를 가져왔다. 헤헤 고마워 :)
1. Application Integration Test
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
------------------------------------
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Import(H2ConsoleProperties.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Transactional
@AutoConfigureMockMvc
public @interface ApplicationIntegrationTest {
...
}
2. Controller Integration Test
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
------------------------------------
@WebMvcTest
@Import({WebSecurityConfig.class, H2ConsoleProperties.class})
@MockBean(JpaMetamodelMappingContext.class)
public @interface ControllerIntegrationTest {
String[] properties() default {};
@AliasFor("controllers")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] controllers() default {};
boolean useDefaultFilters() default true;
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
Class<?>[] excludeAutoConfiguration() default {};
}
3. Controller / Service Test
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
------------------------------------
@ExtendWith(MockitoExtension.class)
public @interface ControllerOrServiceTest {
}
4. Repository Test
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
------------------------------------
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public @interface RepositoryIntegrationTest {
}
https://advenoh.tistory.com/21
https://github.com/Devgather/TIARY/pull/57/files#diff-3c58630cceed2b236d7fd5f51b08fa5cd2f146d17ac174b38ac28cbbec92cda7