Какая самая лучшая среда для создания фиктивных объектов на Java? Почему? Каковы плюсы и минусы каждого фреймворка?
Какой фреймворк для Java лучше всего?
Ответы (14)
Я добился больших успехов в использовании Mockito.
Когда я попытался изучить JMock и EasyMock, я обнаружил, что кривая обучения немного крута (хотя, возможно, это только я).
Мне нравится Mockito из-за его простого и чистого синтаксиса, который я смог довольно быстро понять. Минимальный синтаксис разработан для очень хорошей поддержки общих случаев, хотя несколько раз, когда мне нужно было сделать что-то более сложное, я обнаружил, что то, что я хотел, поддерживалось и было легко понять.
Вот (в сокращении) пример с домашней страницы Mockito:
import static org.mockito.Mockito.*;
List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();
Нет ничего проще.
Единственный серьезный недостаток, о котором я могу думать, это то, что он не будет имитировать статические методы.
Я создатель PowerMock, поэтому, очевидно, должен рекомендовать это! :-)
PowerMock расширяет возможности EasyMock и Mockito с возможностью имитируйте статические методы, final и даже частные методы. Поддержка EasyMock завершена, но над плагином Mockito нужно доработать. Мы также планируем добавить поддержку JMock.
PowerMock не предназначен для замены других фреймворков, скорее его можно использовать в сложных ситуациях, когда другие фреймворки не позволяют имитировать. PowerMock также содержит другие полезные функции, такие как подавление статических инициализаторов и конструкторов.
На сайте проекта JMockit содержится много сравнительной информации о текущих наборах инструментов для имитации.
В частности, просмотрите матрицу сравнения функций, которая охватывает EasyMock, jMock, Mockito, Unitils Mock, PowerMock и, конечно же, JMockit. Я стараюсь, чтобы информация была точной и актуальной, насколько это возможно.
Я добился успеха с JMockit.
Он довольно новый, поэтому немного сыроват и недостаточно документирован. Он использует ASM для динамического переопределения байт-кода класса, чтобы он мог имитировать все методы, включая статические, частные , конструкторы и статические инициализаторы. Например:
import mockit.Mockit;
...
Mockit.redefineMethods(MyClassWithStaticInit.class,
MyReplacementClass.class);
...
class MyReplacementClass {
public void $init() {...} // replace default constructor
public static void $clinit{...} // replace static initializer
public static void myStatic{...} // replace static method
// etc...
}
У него есть интерфейс ожидания, позволяющий также сценарии записи / воспроизведения:
import mockit.Expectations;
import org.testng.annotations.Test;
public class ExpecationsTest {
private MyClass obj;
@Test
public void testFoo() {
new Expectations(true) {
MyClass c;
{
obj = c;
invokeReturning(c.getFoo("foo", false), "bas");
}
};
assert "bas".equals(obj.getFoo("foo", false));
Expectations.assertSatisfied();
}
public static class MyClass {
public String getFoo(String str, boolean bool) {
if (bool) {
return "foo";
} else {
return "bar";
}
}
}
}
Обратной стороной является то, что для этого требуется Java 5/6.
Вы также можете взглянуть на тестирование с помощью Groovy. В Groovy вы можете легко имитировать интерфейсы Java, используя оператор as:
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
Помимо этой базовой функциональности Groovy предлагает гораздо больше насмешек, включая мощные классы MockFor
и StubFor
.
http://docs.codehaus.org/display/GROOVY/Groovy+Mocks
Я начал использовать макеты с EasyMock. Достаточно легко понять, но этап воспроизведения немного раздражал. Mockito удаляет это, а также имеет более чистый синтаксис, поскольку похоже, что читаемость была одна из его основных целей. Я не могу не подчеркнуть, насколько это важно, поскольку большинство разработчиков тратят свое время на чтение и поддержку существующего кода, а не на его создание.
Еще одна приятная вещь заключается в том, что интерфейсы и классы реализации обрабатываются одинаково, в отличие от EasyMock, где вам все еще нужно помнить (и проверять), чтобы использовать расширение класса EasyMock.
Недавно я бегло просмотрел JMockit, и хотя подробный список функций довольно обширен , Я думаю, цена этого - четкость получаемого кода и необходимость писать больше.
Для меня Mockito - это золотая середина: его легко писать и читать, и он справляется с большинством ситуаций, которые потребуются большинству кода. Использование Mockito с PowerMock был бы моим выбором.
Следует учитывать, что инструмент, который вы бы выбрали, если бы вы разрабатывали самостоятельно или в небольшой сплоченной команде, может оказаться не лучшим вариантом для большой компании с разработчиками разного уровня квалификации. В последнем случае необходимо уделить больше внимания удобочитаемости, простоте использования и простоте. Нет смысла получать идеальный фреймворк для имитации, если многие люди в конечном итоге не используют его или не поддерживают тесты.
Мы активно используем в работе EasyMock и EasyMock Class Extension, и нам это очень нравится. Он в основном дает вам все, что вам нужно. Взгляните на документацию, там очень хороший пример, который показывает вам все возможности EasyMock.
Я рано использовал JMock. Я пробовал Mockito на своем последнем проекте, и он мне понравился. Лаконичнее, чище. PowerMock покрывает все потребности, которые отсутствуют в Mockito, такие как имитация статического кода, имитация создания экземпляра, имитация финальных классов и методов. Так что у меня есть все необходимое для работы.
Мне нравится JMock, потому что вы можете устанавливать ожидания. Это полностью отличается от проверки того, был ли вызван метод, найденный в некоторых фиктивных библиотеках. Используя JMock, вы можете писать очень сложные ожидания. См. cheat-sheat jmock.
Да, Mockito - отличный фреймворк. Я использую его вместе с hamcrest и Google guice для настройки моих тестов.
Лучшее решение проблемы имитации - это сделать так, чтобы машина выполняла всю работу с автоматическим тестированием на основе спецификаций. Для Java см. ScalaCheck и Платформа Reductio, включенная в Функциональная библиотека Java. С помощью автоматизированных платформ тестирования на основе спецификаций вы предоставляете спецификацию тестируемого метода (свойство, которое должно быть истинным), и инфраструктура автоматически генерирует тесты, а также имитирующие объекты.
Например, следующее свойство проверяет метод Math.sqrt, чтобы узнать, равен ли квадратный корень любого положительного числа n в квадрате n.
val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }
Когда вы вызываете propSqrt.check()
, ScalaCheck генерирует сотни целых чисел и проверяет ваше свойство для каждого, а также автоматически проверяет, хорошо ли покрыты граничные случаи.
Несмотря на то, что ScalaCheck написан на Scala и требует компилятора Scala, с его помощью легко протестировать код Java. Фреймворк Reductio в функциональной Java - это чистая реализация тех же концепций на Java.
Mockito также предоставляет возможность использования методов-заглушек, сопоставления аргументов (например, anyInt () и anyString ()), проверки количества вызовов (раз (3), atLeastOnce (), never ()), и многое другое.
Я также обнаружил, что Mockito простой и чистый.
В Mockito мне не нравится то, что вы не можете заглушить статические методы а>.
Для чего-то немного другого вы можете использовать JRuby и Mocha, которые объединены в JtestR для написания тестов для вашего Java-кода на выразительном и лаконичном Ruby. здесь есть несколько полезных примеров имитации с JtestR. Одним из преимуществ этого подхода является то, что имитировать конкретные классы очень просто.
Я начал использовать mocks через JMock, но в конце концов перешел на EasyMock. EasyMock был именно таким, более простым, и предлагал более естественный синтаксис. С тех пор я не переходил.