2016-03-21 4 views
0

Я пытаюсь проверить свою вертикулу, но с издевательством MongoDB (чтобы не выполнять реальные действия DB во время модульного тестирования), я попытался издеваться над моим клиентом, но выглядит, когда Я использую vertx.deployVerticle() Мои макеты не принимаются во внимание.Mocking приложение vert.x с PowerMockito

Вот пример моей тестовой установки:

@RunWith(VertxUnitRunner.class) 
@PrepareForTest({ MongoClient.class }) 
public class VerticleTest { 
    @Rule 
    public PowerMockRule rule = new PowerMockRule(); 
    private Vertx vertx; 
    private Integer port; 

    @Before 
    public void setUp(TestContext context) throws Exception { 
    vertx = Vertx.vertx(); 

    mockStatic(MongoClient.class); 

    MongoClient mongo = Mockito.mock(MongoClientImpl.class); 
    when(MongoClient.createShared(any(), any())).thenReturn(mongo); 

    ServerSocket socket = new ServerSocket(0); 
    port = socket.getLocalPort(); 
    socket.close(); 

    DeploymentOptions options = new DeploymentOptions().setConfig(new JsonObject().put("http.port", port)); 
    vertx.deployVerticle(TalWebVerticle.class.getName(), options, context.asyncAssertSuccess()); 
    } 

И то, что я на самом деле видим, что в том, что MongoClient.createShared еще называют, хотя я дразнил его.
Что я могу сделать в этом случае?

Edit 1.
Похоже, проблема в том, что MongoClient является интерфейс и PowerMockito не может издеваться статические методы в этом случае.
Я все еще пытаюсь найти обходное решение для этого случая.

+1

Вы правы, потому что «MongoClient» - это интерфейс и функция, в которой интерфейс может иметь статические методы (или методы), добавленные только в Java 8. И PowerMock по-прежнему не полностью поддерживает Java 8. Но я думаю , ваша проблема может быть легко устранена. В «MainMockTransformer» проверяется, является ли класс, который модифицируется, интерфейсом, а затем пропускает методы модификации. Я думаю об обходном пути для предыдущей версии, и я исправлю это в следующей версии. –

+0

Ничего себе, отличная новость, @ArthurZagretdinov. Тем временем я попробую 'JMockIt', есть люди, которые говорят, что это может сработать. Посмотрим ... – WhiteAngel

ответ

1

Я не знал, что MongoClient является интерфейсом, после чего я дал свой первый ответ.

PowerMock не поддерживает насмешливые интерфейсы статических вызовов (ошибка #510, исправлено исключение Javaassist, но издевательские статические методы по-прежнему не поддерживаются). Он будет вызываться в следующем выпуске.

Я занимался вопросом в PowerMock, а не почему это необходимо. Я согласен с ответом, который был представлен в Mailing List.

Вы могли бы работать вокруг него, создавая вспомогательный метод в собственном коде , который возвращает MongoClient.createdShared(). Затем в тесте, издеваться, что помощник вернуть высмеивал MongoClientImp

Но это будет не работа вокруг, но правильное решение дизайна. Mocking MongoClient не очень хороший подход, потому что you should not mock types you don't own.

Таким образом, лучший способ создать пользовательский помощник, который создаст для вас MongoClient, а затем издевается над этим помощником в модульном тесте. Также вам понадобятся интеграционные тесты для этого помощника, который будет называться реальным MongoClient.createdShared().

Если у вас нет возможности изменить код (или вы не хотите менять код без тестов), то я создаю example с тем, как можно обойти ошибку PowerMock.

Основные идеи:

  • создать пользовательские MainMockTransformer. Трансформатор преобразует классы интерфейсов, чтобы поддерживать поддерживающие макетные статические вызовы для интерфейсов.
  • создать пользовательский PowerMockRunner, который будет использоваться для добавления настраиваемого MockTransformer в цепи трансформаторов.

Пожалуйста, обратите внимание на имя пакета, в котором расположены эти новые классы. Это важно. Если вы хотите переместить их в другие пакеты, вам нужно будет добавить эти новые пакеты в @PowerMockIgnore.

+0

Извините за эту путаницу, это всего лишь немного сломанный код в моем первом коде. Я удалил его случайно, удалив ненужные части. Даже с 'mockStatic (MongoClient.class)' он терпит неудачу. Спасибо, я обновлю свой первоначальный пост. – WhiteAngel

+0

Я изменил ответ. –