2014-10-15 2 views
6

Кто-нибудь знает, как добавить тестовый ресурс (т. Е. Тот, который предназначен только для тестирования и не добавлен в метод run() приложения)?Интегрированное тестирование Dropwizard с TestResource

Вот пример:

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

и

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

Моя проблема заключается в том, что добавленный ресурс не будет добавлен и я получаю ресурс не найден ответ 404 ошибки. Кажется, что я регистрирую новый ресурс после публикации ресурсов, и после запуска обновления в 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"); 
+0

Что-то вроде RULE.addRessource (...) будет nice ... – user3280180

ответ

5

Редактировать: Удаление предыдущего ответа, поскольку оно не решило вашу проблему так, как вы хотели это сделать.

Я ворвался в код запуска среды и понял, почему регистрация контроллера не делает его доступной, потому что причал уже запущен. Если вы остановите причал, зарегистрируйте свой контроллер и снова запустите причал, ваш ресурс будет доступен, и вы сможете использовать его в своем тесте.

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

Да, но тогда у меня есть дополнительный тестовый код в моем приложении. Чтобы предотвратить создание еще лучшего класса, который расширяет MyApplication и перезаписывает run(), как я упоминал выше. Но я попросил лучшего решения добавить ресурс только в TestClass, и именно поэтому я не могу согласиться с вашим решением. – user3280180

+0

Не могли бы вы объяснить, почему три строки кода, специфичные для проверки переменной среды, являются неприемлемым вариантом? – th3morg

+0

Я избегаю Testcode в LiveCode, поэтому даже мой класс TestService расширяет MyService - лучшее решение, потому что у меня нет методов «только для тестирования» в моем приложении. С помощью этого перезаписанного метода run() я могу четко отделить свой тестовый и livecode. С вашим решением можно было бы сделать неправильную конфигурацию внутри вашего живого * .yml, а затем у вас есть строки кода для тестирования в вашем приложении. – user3280180

2

Вы можете проверить сам ресурс в Джерси контейнер без запуска полного с.в. -пример.

Проверьте "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"); 
    } 
} 
+0

Я уже создал тесты ресурсов, но я вставил новый фильтр, и поэтому мне нужен «полный dw-экземпляр». – user3280180

0

Я имел аналогичный вопрос с @ClassRule, может быть, это может помочь кому-то ..
В моем тесте (Groovy) призывание RULE.getApplication() или getEnvironment() из метода @BeforeClass вернулся нуль:

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

показано

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

Т.е. У RULE.testSupport были и нулевое приложение, и среда.

Я узнал, что звонок в RULE.testSupport.раньше() непосредственно перед запуском() решает ошибку:

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

А потом @AfterClass метода:

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

Или просто использовать @Rule вместо @ClassRule и называют

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

внутри метода @Before вместо @BeforeClass.
Хотя это кажется странным, может быть, есть некоторые другие лучшее решение существует ..

0

общественный класс 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(); 
         } 
        }); 
} 

}

+0

просто расширьте основной класс, а затем добавьте тестовые материалы, которые должны работать, я инициализирую h2 in-mem DB только для проверки этого пути – gli00001

Смежные вопросы