-
Notifications
You must be signed in to change notification settings - Fork 41.4k
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?