java Dropwizard 与 TestResource 的集成测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26381170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 09:49:34  来源:igfitidea点击:

Dropwizard Integrated Testing with TestResource

javaresttestingdropwizard

提问by user3280180

Does anyone knows how to add a test Resource (i.e. one that is only for testing purposes and not added in run() method of the app)?

有谁知道如何添加测试资源(即仅用于测试目的且未添加到应用程序的 run() 方法中的资源)?

Here is an example:

下面是一个例子:

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

and

public class JustForTestingRessource {


    @GET
    @Path("test")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getInTestResource()
    {
        return Response.status(Status.OK).type(MediaType.TEXT_PLAIN).entity("get @Path(\"test\") is ok").build();
    }
}

My problem is that the added resource is not added and I get resource not found 404 error response. It seems that I am registering the new resource after resource publishing and there is no refresh inside Dropwizard after start.

我的问题是添加的资​​源没有添加,我得到资源未找到 404 错误响应。好像是资源发布后注册新资源,启动后Dropwizard里面没有刷新。

I dont want to extend my Application class and I dont want to insert test code into my real application code. Does anyone knows how to register the test resource without registering it in run() method of the Application?

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

This works, but a new class is needed:

这有效,但需要一个新类:

public class TestService extends MyService{


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

}

Call in JUnit as already known:

以已知的方式调用 JUnit:

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

采纳答案by th3morg

Edit: Removing previous answer because it didn't solve your problem the way you wanted to do it.

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

I dug into the environment startup code and realized the reason why registering a controller didn't make it available is because jetty had already been started. If you stop jetty, register your controller and start jetty back up again, your resource will be available and you can use it in your test.

我深入研究了环境启动代码,意识到注册控制器没有使其可用的原因是因为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()
}

回答by Jan Galinski

You can test the Resource itself in a Jersey Container without starting a full dw-instance.

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

Check the "Testing Resources" section.

检查“测试资源”部分

import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

public class PersonResourceTest {

     private static final PeopleStore dao = mock(PeopleStore.class);

     @ClassRule
     public static final ResourceTestRule resources = ResourceTestRule.builder()
        .addResource(new PersonResource(dao))
        .build();

     private final Person person = new Person("blah", "[email protected]");

     @Before
     public void setup() {
         when(dao.fetchPerson(eq("blah"))).thenReturn(person);
         // we have to reset the mock after each test because of the
         // @ClassRule, or use a @Rule as mentioned below.
         reset(dao);
     }

     @Test
     public void testGetPerson() {
         assertThat(resources.client().resource("/person/blah").get(Person.class))
            .isEqualTo(person);
         verify(dao).fetchPerson("blah");
     }
 }

回答by dim42

I had the similar issue with the @ClassRule, maybe it can help to somebody..
In my test (Groovy) the invocation of RULE.getApplication() or getEnvironment() from @BeforeClass method returned null:

我对@ClassRule 有类似的问题,也许它可以对某人有所帮助..
在我的测试(Groovy)中,@BeforeClass 方法调用 RULE.getApplication() 或 getEnvironment() 返回空值:

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

shown

显示

java.lang.NullPointerException: Cannot invoke method run() on null object

I.e. RULE.testSupport had both null application and environment.

即 RULE.testSupport 有空应用程序和环境。

I found out that the call to RULE.testSupport.before() just before run() solves the error:

我发现在 run() 之前调用 RULE.testSupport.before() 解决了错误:

def setupSpec() {
    RULE.testSupport.before()
    RULE.application.run()
}

And then @AfterClass method:

然后@AfterClass 方法:

def cleanupSpec() {
    RULE.testSupport.after()
}

Or just use @Rule instead of @ClassRule and call

或者只是使用 @Rule 而不是 @ClassRule 并调用

def setup() {
    RULE.application.run()
}

inside of @Before method instead of @BeforeClass.
Though It seems strange, maybe there is some other better solution exists..

@Before 方法内部而不是 @BeforeClass。
虽然看起来很奇怪,但也许还有其他更好的解决方案存在..

回答by gli00001

public class TestMain extends Main{

公共类 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();
                        }
                    });
}

}

}