Java Dropwizard与TestResource集成测试

Java Dropwizard与TestResource集成测试,java,rest,testing,dropwizard,Java,Rest,Testing,Dropwizard,是否有人知道如何添加测试资源(即,仅用于测试目的而未添加到应用程序的run()方法中的资源) 以下是一个例子: public class MyTest { @ClassRule public static final DropwizardAppRule<TestConfiguration> RULE = new DropwizardAppRule<TestConfiguration>(MyApp.class, "my-app-

是否有人知道如何添加测试资源(即,仅用于测试目的而未添加到应用程序的run()方法中的资源)

以下是一个例子:

public class MyTest {   
    @ClassRule
    public static final DropwizardAppRule<TestConfiguration> RULE =
            new DropwizardAppRule<TestConfiguration>(MyApp.class, "my-app-config.yaml");


    @BeforeClass
    public static void setUpBeforeClass() throws Exception
    {
        MyTest.RULE.getEnvironment().jersey().register(new JustForTestingResource());
    }


    @Test
    public final void testTestResource()
    {
        Client client = new Client();

        ClientResponse response = client.resource(
            String.format("http://localhost:%d/rest/v1/test", RULE.getLocalPort()))
            .get(ClientResponse.class);

        assertThat(response.getStatus(), is(200));   
    }
}
我的问题是添加的资源没有被添加,我得到了ResourceNotFound404错误响应。看来我是在资源发布后注册新资源的,启动后Dropwizard内部没有刷新

我不想扩展我的应用程序类,也不想将测试代码插入到我真正的应用程序代码中。有人知道如何注册测试资源而不在应用程序的run()方法中注册它吗

这是可行的,但需要一个新类:

public class TestService extends MyService{


    @Override
    public void run(
        TestConfigurationconfiguration,
        Environment environment) throws ClassNotFoundException
    {       
        environment.jersey().register(new JustForTestingRessource());
        super.run(configuration,environment);
    }

}
调用已知的JUnit:

@ClassRule
public static DropwizardAppRule<TestConfiguration> RULE =
        new DropwizardAppRule<TestConfiguration>(TestService.class, "my-app-config.yaml");
@ClassRule
公共静态删除规则=
新的DropwizardAppRule(TestService.class,“my app config.yaml”);

您可以在Jersey容器中测试资源本身,而无需启动完整的dw实例

检查一下


编辑:删除以前的答案,因为它没有按您希望的方式解决您的问题

我深入研究了环境启动代码,意识到为什么注册一个控制器不能使它可用是因为jetty已经启动了。如果您停止jetty,注册控制器并重新启动jetty,您的资源将可用,您可以在测试中使用它

@BeforeClass
public static void setUpBeforeClass() throws Exception
{
    MyTest.RULE.environment.applicationContext.stop()
    MyTest.RULE.environment.jersey().register(new JustForTestingResource())
    MyTest.RULE.environment.applicationContext.start()
}

我对@ClassRule也有类似的问题,也许它对某些人有帮助。
在我的测试(Groovy)中,从@BeforeClass方法调用RULE.getApplication()或getEnvironment()时返回null:

def setupSpec() {
    RULE.application.run()
}
显示

也就是说,RULE.testSupport的应用程序和环境都为空

我发现打电话给 RULE.testSupport.before() 就在run()解决错误之前:

def setupSpec() {
    RULE.testSupport.before()
    RULE.application.run()
}
然后@AfterClass方法:

def cleanupSpec() {
    RULE.testSupport.after()
}
或者只使用@Rule而不是@ClassRule并调用

def setup() {
    RULE.application.run()
}
在@Before方法内部,而不是@BeforeClass。

虽然看起来很奇怪,但可能还有其他更好的解决方案。

公共类TestMain扩展了Main{

public static void main(String ... args) throws Exception {
    new TestMain().run(args);
}


@Override
public void initialize(Bootstrap<AppConfiguration> bootstrap) {
    super.initialize(bootstrap);
    bootstrap.addBundle(
                    new MigrationsBundle<AppConfiguration>() {
                        @Override
                        public DataSourceFactory getDataSourceFactory(
                                        AppConfiguration configuration) {
                            return configuration.getDataSourceFactory();
                        }
                    });
}
publicstaticvoidmain(String…args)引发异常{
新建TestMain().run(args);
}
@凌驾
公共无效初始化(引导引导引导){
初始化(引导);
bootstrap.addBundle(
新的迁移包(){
@凌驾
公共数据源工厂getDataSourceFactory(
AppConfiguration(配置){
返回配置。getDataSourceFactory();
}
});
}

}

我已经创建了资源测试,但是我插入了一个新的过滤器,这就是为什么我需要“完整的dw实例”。是的,但是我的应用程序中还有额外的测试代码。为了避免这种情况,最好创建一个扩展MyApplication的类,并像上面提到的那样覆盖run()。但是我要求一个更好的解决方案,只在TestClass中添加一个资源,这就是为什么我不能同意你的解决方案。你能详细说明为什么三行特定于检查环境变量的代码是一个不可接受的选项吗?我避免在LiveCode中使用Testcode,所以即使我的类TestService扩展了MyService也是一个更好的解决方案,因为我的应用程序中没有“仅用于测试目的”的方法。使用这个重写的run()方法,我可以清楚地将测试代码和活动代码分开。使用您的解决方案,可能会在live*.yml中执行错误的配置,然后您的应用程序中就有了用于测试的代码行。@user3280180请查看我的更新答案。我相信这对你来说应该是可行的,测试本身之外不需要任何代码。是的,现在它停止并用新资源重新启动,但我添加了启动后1000毫秒的睡眠。因此,最初的问题得到了回答,即使我现在有一些其他例外,但我不知道这是我自己的问题还是由于重新启动。我将此标记为已解决!类似RULE.addRessource(…)的东西会很好…只需扩展主类,然后添加测试特定的东西就可以了,我在memdb中初始化h2就是为了用这种方式进行测试
def cleanupSpec() {
    RULE.testSupport.after()
}
def setup() {
    RULE.application.run()
}
public static void main(String ... args) throws Exception {
    new TestMain().run(args);
}


@Override
public void initialize(Bootstrap<AppConfiguration> bootstrap) {
    super.initialize(bootstrap);
    bootstrap.addBundle(
                    new MigrationsBundle<AppConfiguration>() {
                        @Override
                        public DataSourceFactory getDataSourceFactory(
                                        AppConfiguration configuration) {
                            return configuration.getDataSourceFactory();
                        }
                    });
}