单元测试ContainerRequestFilter,它使用ResourceInfo和mockito
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单元测试ContainerRequestFilter,它使用ResourceInfo和mockito相关的知识,希望对你有一定的参考价值。
我正在尝试使用Mockito对使用@NameBinding应用的ContainerRequestFilter进行单元测试。过滤器检查注释字段以确定要执行的操作。请参阅示例代码:
注解
@Target({TYPE, METHOD})
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
MyEnum info() default MyEnum.DEFAULT;
}
Myenm
public enum MyEnum {
VALUE1,
VALUE2,
DEFAULT
}
带注释的过滤器,使用MyEnum作为条件
@MyAnnotation
public class MyFilter implements ContainerRequestFilter {
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
if (resourceInfo.getResourceMethod().getAnnotation(MyAnnotation.class).info().equals(MyEnum.VALUE1))
{
// set some value or throw some exception (this can be verified in the test)
}
if (resourceInfo.getResourceMethod().getAnnotation(MyAnnotation.class).info().equals(MyEnum.VALUE2))
{
// set some value or throw some exception (this can be verified in the test)
}
}
}
带注释的资源方法
@Path("/somepath1")
public class MyResource1
{
@GET
@MyAnnotation(info = MyEnum.VALUE1)
public Response someResourceMethod()
{
// return response
}
}
@Path("/somepath2")
public class MyResource2
{
@GET
@MyAnnotation(info = MyEnum.VALUE2)
public Response someResourceMethod()
{
// return response
}
}
当有新的条件要添加到过滤器时,此设计可以轻松添加枚举值。
如何通过改变条件中的值来对MyFilter
进行单元测试?
我试过的一种方法是模拟ResourceInfo
,然后在Method
时返回模拟resourceInfo.getResourceMethod()
,但由于Method是最后一课,所以不能这样做。
也不推荐使用您不拥有的模拟对象,因此有不同的方法来测试它吗?我也没有和Mockito结婚,所以对任何其他建议持开放态度。
答案
最简单的方法是为测试创建一个虚拟类,并做一点反思以获得类中的Method
@Test
public void testEnumOne() throws Exception {
Method methodOne = MockClass.class.getDeclaredMethod("enumOne");
Mockito.when(resourceInfo.getResourceMethod()).thenReturn(methodOne);
}
private static class MockClass {
@MyAnnotation(info=MyEnum.VALUE1)
public void enumOne() {}
@MyAnnotation(info=MyEnum.VALUE2)
public void enumTwo() {}
}
这是一个完整的测试。
@RunWith(MockitoJUnitRunner.class)
public class FilterAnnotationTest {
@Mock
private ResourceInfo resourceInfo;
@Mock
private ContainerRequestContext context;
@Spy
private Service service;
private MyFilter filter;
@Before
public void setUp() {
filter = new MyFilter(resourceInfo, service);
}
@Test
public void testEnumOne() throws Exception {
Method methodOne = MockClass.class.getDeclaredMethod("enumOne");
Mockito.when(resourceInfo.getResourceMethod()).thenReturn(methodOne);
filter.filter(context);
Mockito.verify(service).methodOne();
}
@Test
public void testEnumTwo() throws Exception {
Method methodTwo = MockClass.class.getDeclaredMethod("enumTwo");
Mockito.when(resourceInfo.getResourceMethod()).thenReturn(methodTwo);
filter.filter(context);
Mockito.verify(service).methodTwo();
}
private enum MyEnum {
VALUE1, VALUE2
}
@Target({ METHOD })
@Retention(RUNTIME)
private @interface MyAnnotation {
MyEnum info();
}
private static class MyFilter implements ContainerRequestFilter {
private final ResourceInfo resourceInfo;
private final Service service;
@Inject
public MyFilter(ResourceInfo resourceInfo, Service service) {
this.resourceInfo = resourceInfo;
this.service = service;
}
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
MyAnnotation anno = resourceInfo.getResourceMethod().getAnnotation(MyAnnotation.class);
if (anno.info() == MyEnum.VALUE1) {
service.methodOne();
} else if (anno.info() == MyEnum.VALUE2) {
service.methodTwo();
}
}
}
private static class MockClass {
@MyAnnotation(info=MyEnum.VALUE1)
public void enumOne() {}
@MyAnnotation(info=MyEnum.VALUE2)
public void enumTwo() {}
}
public interface Service {
void methodOne();
void methodTwo();
}
}
以上是关于单元测试ContainerRequestFilter,它使用ResourceInfo和mockito的主要内容,如果未能解决你的问题,请参考以下文章