Как проверить сервис отдыха на Джерси, используя фиктивные объекты

1

Я разработал сервис отдыха с использованием Джерси. Теперь я хочу написать некоторые интеграционные тесты для этого веб-сервиса, но так как не каждый класс, используемый из веб-службы, уже реализован, мне нужно издеваться над некоторыми из них. Например, у меня есть следующий класс:

public class A {

    private String getWeather() {
        return null;
    }
}

Мой веб-сервис выглядит так:

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

    @GET 
    @Produces("text/plain")
    public String getIt() {
        A a = new A();
        return a.getWeather();
    }
}

Проблема в том, что функция getWeather не готова, поэтому мне нужно высмеять возвращаемое значение для этой функции. Но для теста интеграции, в котором я делаю вызов для отдыха, я не знаю, как это сделать.

Есть идеи?

  • 0
    хорошо вы пробовали использовать Mockito? Вы можете getWeather вызов getWeather и вернуть объект test string для тестов. Посмотрите code.google.com/p/mockito
  • 1
    Это не работает, потому что внутри ресурса rest создается новый экземпляр класса A, поэтому фиктивный объект не используется.
Теги:
rest
integration-testing
mocking
jersey

2 ответа

2
Лучший ответ

Вы можете достичь этого, используя Power Mockito (https://code.google.com/p/powermock/wiki/MockitoUsage)

@RunWith(PowerMockRunner.class)
@PrepareForTest({ MyResource.class })
public class MyResourceTest {

   @Test
   public void testGetIt()() {
     MyResource mr = new MyResource();

     //Setup mock
     A mockA = PowerMockito.mock(A.class);

     String mockReturn = "Some String";

     //Stub new A() with your mock
     PowerMockito.whenNew(A.class).withAnyArguments().thenReturn(mockA);
     PowerMockito.doReturn(mockReturn).when(mockA).getWeather();
     String ret = mr.getIt();

     //asserts go here
   }
}

Обратите внимание, что вы можете издеваться над созданием локальной переменной с помощью PowerMockito whenNew - это должно позаботиться о вашей проблеме для A a = new A() кода A a = new A() в getIt().

  • 0
    Поскольку я хочу запустить интеграционный тест, я не создаю экземпляр MyResource, но вызываю службу с помощью Rest Client. Я пытался использовать mockito, но он использует не функцию mocked, а оригинальную.
  • 0
    На самом деле это работает, если он используется вместе с тестовой платформой Джерси! Большое спасибо !
Показать ещё 2 комментария
3

Чтобы разделить дизайн на A, вы должны передать его в качестве параметра MyResource. Тогда вы можете легко издеваться над ним вручную или с помощью mockito. При инсталляции конструктора это будет выглядеть так:

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

    private A a;

    public MyResource(A a) {
        this.a = a;
    }

    @GET 
    @Produces("text/plain")
    public String getIt() {
        return a.getWeather();
    }
}

и вы можете проверить его с помощью

@Test
public void shouldGetIt() {
    A a = mock(A.class);
    when(a.getWeather()).thenReturn("sunny!");

    MyResource r = new MyResource(a);
    assertThat(r.getIt(), is("sunny!));
}

Это делает ваш дизайн развязанным. MyResource больше не зависит от A напрямую, а от чего-то похожего на A. Другое преимущество заключается в том, что mockito не вмешивается в ваши файлы классов. Это ваш код, который протестирован - не то, что было создано "на лету".

Многие считают инъекцию конструктором немного старой школы. Я стар, поэтому мне это нравится... С весной (рамки, которую я не рекомендую вам подбирать) вы можете автоувеличивать такие переменные:

@Autowire
private A a;

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню