【问题标题】:register multiple resource instances of same type注册多个相同类型的资源实例
【发布时间】:2024-05-17 03:00:01
【问题描述】:

我有一个资源端点,它将 @PathParam 注入构造函数,即每个 @PathParam 值的不同实例。在 Jetty 中一切正常。但是现在我正在尝试使用 Jersey 测试框架编写单元测试,并且似乎测试框架只支持每种类型的一个注册端点。

所以如果我这样做:

@Path("/users")
public class MyResource {

    public MyResource(@PathParam("userId") int userId) {
    }

    @Path("{userId}")
    public String get() {

    }
}

public class MyTest extends JerseyTestNg.ContainerPerClassTest {

    @Override
    protected Application configure() {
        return new ResourceConfig()
                .register(new MyResource(1))
                .register(new MyResource(2));
    }

    @Test
    public void test2() {
        target("/users/1").request().get();
    }

    @Test
    public void test2() {
        target("/users/2").request().get();
    }
}

我看到 test1 和 test2 都在调用 MyResource(1) 的实例。这是预期的吗?是否有调用正确实例的解决方案?

【问题讨论】:

  • 你应该把它注册为一个类。泽西岛将为您创建它。
  • 我发布的例子是愚蠢的。实际上,我的资源构造函数有另一个需要模拟的注入对象。那么如何为构造函数指定一个模拟对象参数呢?
  • 您使用的是什么 DI 框架?你用的是内置的HK2吗?
  • 我们的应用程序通过 hk2 桥接器使用 guice,但在这个单元测试中我没有配置 guice 或任何其他 di。

标签: jersey jersey-test-framework


【解决方案1】:

您应该将资源注册为一个类。泽西岛将为您创建它。并处理所有的注射。

“我发布的示例被简化了。实际上,我的资源构造函数有另一个我需要模拟的注入对象。那么我该如何为构造函数指定一个模拟对象参数?”

你可以这样做

@Mock
private Service service;

@Override
public ResourceConfig configure() {
    MockitoAnnotations.initMocks(this);
    return new ResourceConfig()
        .register(MyResource.class)
        .register(new AbstractBinder() {
            @Override
            protected configure() {
                bind(service).to(Service.class);
            }
        });
}

@Test
public void test() {
    when(service.getSomething()).thenReturn("Something");
    // test
}

假设您已经在使用内置的 HK2 DI,并且在资源类的构造函数上有 @Inject 注释,这应该可以工作。在AbstractBinder 中,我们使模拟对象可注入。所以现在 Jersey 可以将它注入到你的资源中。

另请参阅:

【讨论】:

    最近更新 更多