Первый шаг после получения Google Contracts для Java Jar и добавления его в ваш проект — включить поддержку обработки аннотаций в IDEA.
Для этого откройте окно настроек ( IntelliJ IDEA> настройки на Mac) и перейдите в Компилятор> Процессоры аннотаций .
Теперь сделайте следующие шаги:
- Установите флажок Включить обработку аннотаций.
- Выберите параметр Получить процессоры из пути к классам проекта.
- В таблице «Обработанные модули» нажмите кнопку «Добавить» и выберите модуль, для которого вы хотите включить контракты.
- Нажмите Применить, и вы готовы к рок.
Чтобы проверить это, вы можете добавить базовую аннотацию контракта к методу в классе, вот тот, который я создал, используя аннотацию @Requires, чтобы гарантировать, что целочисленный параметр метода «c» имеет значение больше нуля:
import com.google.java.contract.Requires;
public class TestSomeContracts {
@Requires({"c > 0"})
public void testContract(int c) {
}
}
Теперь, когда вы компилируете, вы не получите много отзывов о том, была ли аннотация обработана или нет, так как синтаксис контракта правильный, поэтому давайте немного изменим его, чтобы генерировать знак компиляции, изменив имя переменной предусловия:
@Requires({"cs > 0"})
public void testContract(int c) {
}
При сборке модуля вы получите ошибку компиляции, которая как бы интегрируется в IDEA, в которой вы можете нажать на ошибку в окне сообщений, и вы попадете на строку, которая не удалась. К сожалению, IDEA не будет выделять строку в вашем редакторе или что-то необычное, например, то, что вы получаете в Eclipse, но этого достаточно для работы.
Использование класса с контрактами.
После возврата и компиляции класса я создал простой тестовый пример для проверки договора, передавая данные, которые нарушают договор (т. Е. Целое число меньше 1):
import org.junit.Test;
public class TestSomeContractsTest {
@Test
public void testContract() {
new TestSomeContracts().testContract(-1);
}
}
Я запускаю тест … и … он проходит!
Для того, чтобы на самом деле работать, Google Contracts должен выполнить некоторые байт-коды shenanigans, чтобы обеспечить принудительное применение определений контрактов во время выполнения. В настоящее время у них есть два режима работы: автономный инструментарий, который представляет собой процессор посткомпиляции, который объединяет контракты в скомпилированный класс, и агент Java.
Для разработки наиболее удобным методом является Java-агент.
Чтобы использовать агент в IDEA, щелкните раскрывающийся список « Выберите параметры запуска / отладки» и выберите параметр « Изменить конфигурации» . Разверните запись по умолчанию и выберите опцию JUnit (или TestNG или просто приложение ) и добавьте следующее в поле параметров виртуальной машины :
-javaagent: [путь к файлу jar контрактов Google для Java]
Я также удаляю существующую конфигурацию, чтобы она выбрала новую опцию при повторном запуске теста.
Теперь я снова запускаю тест и — вуаля — хороший большой сплат, когда я запускаю тест и передаю неверные данные методу:
com.google.java.contract.PreconditionError: c > 0
at TestSomeContracts.com$google$java$contract$PH$TestSomeContracts$testContract(TestSomeContracts.java:9)
at TestSomeContracts.testContract(TestSomeContracts.java)
at TestSomeContractsTest.testContract(TestSomeContractsTest.java:9)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
На последнем замечании. Контракты с Google все еще довольно свежи, поэтому мы надеемся, что поддержка IDE улучшится, если проект будет запущен. Должен также сказать, что мне не очень нравятся нынешние механизмы обеспечения исполнения контракта. Надеюсь, Google может взять страницу из Lombok и сделать ткачество во время компиляции.
От http://dotneverland.blogspot.com/2011/02/using-google-contracts-for-java-with.html