2016-02-03 1 views
0

Я запускаю PowerMock 1.6.4 и все последние (JUnit 4.11 хотя).Оффлайн Jacoco, использующий MockStatic, вызывает повторное использование инструментария

  • Я использую задачу Jacoco Ant, чтобы обрабатывать классы, а не классы тестов. Я также использую задачу Jacoco ant для запуска тестов Junit, а затем генерирую отчеты.

Теперь я ударяя проблема, которую я не могу понять ...

  • У меня есть тестовый класс, который проверяет одну функцию-член класса Foo.
  • Один из членов Foo является статическим, поэтому я обернул это в статической функции, чтобы я мог контролировать выполнение с помощью mock, но побочный эффект заключается в том, что мне сейчас нужно mockStatic.

То, что я заметил, что PowerMockito.mockStatic (Foo.class) ... все тесты не с проблемами приборов.

У меня есть еще один тестовый класс, который проверяет другую функцию-член Foo. Этот класс тестов отлично работает, но как только я введу mockStatic, тестовый класс терпит неудачу с отказом аппаратуры.

Кто-нибудь видит эту ошибку и знает какие-либо обходные пути? Я не могу изменить статическую переменную-член.

+0

Я считаю, что приборы должны быть выполнены на тестах, а не на классах. По крайней мере, в моем проекте единственное, что нужно измерить, это мои тестовые классы, а остальные мои классы исключены. Попробуйте это, и если это не сработает, опубликуйте файл pom/ant, чтобы я мог посмотреть на него немного больше. – Lencalot

ответ

0

Наконец-то я понял, в чем я уверен. Инструмент Jacoco вводит данные в ваш байт-код, поэтому PowerMock пытается попытаться имитировать статику. Это разрушает хаос, поскольку они наступают друг на друга, и вы получите действительно странное поведение из-за того, что они возились друг с другом. Я получал разнообразную группу NPE в коде, которая не должна бросать NPE.

Простым решением было реорганизовать ненужную статику и знать, что если вы планируете использовать статику для управления потоком данных, возможно, следует пересмотреть архитектуру для тестирования, если вы планируете использовать Jacoco для покрытия.

Вы все еще можете использовать приборы Jacoco для статики, но вы не можете одновременно издеваться над статикой; по крайней мере, не так, как это делает PowerMock с Mockito. Я не уверен, что EasyMock приведет к другому поведению, поэтому ymmv.

0

У меня были подобные проблемы, но вместо того, чтобы реорганизовать статику, я считаю, что есть еще одно решение. Я сделал это в файле maven mom, но я объясню, что происходит. Jacoco вводит данные в ваш байтовый код. И да, Powermock использует пользовательский байтовый загрузчик, и Жакоко ненавидит это. Таким образом, это решение, чтобы обойти это.

В ваших исполнениях Jacoco вам понадобится Jacoco для использования инструментов по умолчанию для ваших тестов. (вы можете указать тесты powermock или просто включить все тесты, которые он работает в любом случае). Heres объяснение того, что происходит с дефолтом - Instrumentation: Offline-instrumentation with Jacoco.

Затем вы должны выполнить этап восстановления для тестов. Теперь вот интересная часть, вам нужно запустить обычный шаг агента Jacoco Prepare Agent, ИСКЛЮЧАЯ все тесты, которые выполнялись по умолчанию. (если вы этого не сделаете, вы получите кучу предупреждений о том, что данные об исключении JaCoCo уже существуют для xTest).

Это позволит решить вашу проблему, и вам не нужно реорганизовывать свои статические методы.Хотя, если они не нужны, вы, вероятно, все равно должны их вытащить;)

<plugin> 
       <groupId>org.jacoco</groupId> 
       <artifactId>jacoco-maven-plugin</artifactId> 
       <version>${jacoco.version}</version> 
       <configuration> 
        <append>true</append> 
       </configuration> 
       <executions> 
        <execution> 
         <id>default-instrument</id> 
         <goals> 
          <goal>instrument</goal> 
         </goals> 
         <configuration> 
          <includes> 
           <include>**/*test*</include> 
          </includes> 
         </configuration> 
        </execution> 
        <execution> 
         <id>default-restore-instrumented-classes</id> 
         <goals> 
          <goal>restore-instrumented-classes</goal> 
         </goals> 
         <configuration> 
          <includes> 
           <include>**/*test*</include> 
          </includes> 
         </configuration> 
        </execution> 
        <execution> 
         <id>Prepare-Jacoco</id> 
         <goals> 
          <goal>prepare-agent</goal> 
         </goals> 
         <configuration> 
          <excludes> 
           <exclude>**/*test*</exclude> 
          </excludes> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
Смежные вопросы