-
Notifications
You must be signed in to change notification settings - Fork 41.6k
Description
I want to test a REST Controller in my spring boot project, I wrote the following code:
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(MetaInfoController.class)
@TypeExcludeFilters({TypeExcludeFilterForControllerTest.class})
public class MetaInfoControllerTest {
// ....
}
The TypeExcludeFilterForControllerTest class is as follows:
public class TypeExcludeFilterForControllerTest extends TypeExcludeFilter {
private static final List<String> EXCLUDE_CLASS_NAMES = Arrays.asList(WebConfig.class.getName(), MyCasAuthenticationFilter.class.getName());
@Override
public boolean match(final MetadataReader metadataReader, final MetadataReaderFactory metadataReaderFactory) throws IOException {
return EXCLUDE_CLASS_NAMES.contains(metadataReader.getClassMetadata().getClassName());
}
}
The purpose I did this is to prevent some classes from being loaded to spring application context, in addition to @WebMvcTest.
But, when I run the tests, I got the following error:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'metaInfoService' defined in file [/xx/xx/MetaInfoService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'metaMapper' defined in file [/xx/xx/metaMapper.class]:
// ... more
It seems that the @TypeExcludeFilters(WebMvcTypeExcludeFilter.class) which is inside the @WebMvcTest does not work. To demonstrate my opinion, I debugged into the source code, and I found the reason.
During the test context building process, one step is to create a context customizer for TypeExcludeFiltersContextCustomizer, and this is done by calling the createContextCustomizer() method of TypeExcludeFiltersContextCustomizerFactory class. This method calls the AnnotatedElementUtils.findMergedAnnotation() to get the @TypeExcludeFilters defination. According to the java doc of findMergedAnnotation(), it will only get the first found @TypeExcludeFilters defination and return it, so, the @TypeExcludeFilters(WebMvcTypeExcludeFilter.class) of @WebMvcTest is ignored.
To resolve this problem, I tried to add the WebMvcTypeExcludeFilter.class to mine outside @TypeExcludeFilters defination like this:
@TypeExcludeFilters({TypeExcludeFilterForControllerTest.class, WebMvcTypeExcludeFilter.class})
But I found that the access modifier of WebMvcTypeExcludeFilter is Default, so it can not be accessed from outside the package.
So my question is: Is it possible to change 'WebMvcTypeExcludeFilter' class to be public?
Or, is there any other workaround solution?