gpt4 book ai didi

java - 将 ResourceInfo 与 mockito 结合使用的单元测试 ContainerRequestFilter

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:03:04 28 4
gpt4 key购买 nike

我正在尝试使用 Mockito 对使用 @NameBinding 应用的 ContainerRequestFilter 进行单元测试。过滤器检查注释字段以确定要做什么。查看示例代码:

注释

@Target({TYPE, METHOD})
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
MyEnum info() default MyEnum.DEFAULT;
}

我的枚举

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,然后在 resourceInfo.getResourceMethod() 时返回模拟 Method,但这无法完成,因为方法是最后一个类。

此外,不建议模拟您不拥有的对象,那么是否有不同的方法来测试它?我也不喜欢 Mockito,因此愿意接受任何其他建议。

最佳答案

最简单的方法是为测试创建一个虚拟类,并进行一些反射以获取该类的方法

@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();
}
}

关于java - 将 ResourceInfo 与 mockito 结合使用的单元测试 ContainerRequestFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45576542/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com