Какой лучший макет фреймворка для 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, позволяя имитировать статические методы, финальные и даже частные методы. Поддержка 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, вы можете написать очень сложные ожидания. Посмотрите на болтовню.

Да, 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()), проверки количества вызовов (times(3), atLeastOnce(), never()) и многого другого.

Я также обнаружил, что Mockito прост и чист.

В Mockito мне не нравится то, что вы не можете заглушить статические методы.

Для чего-то немного другого, вы можете использовать JRuby и Mocha, которые объединены в JtestR, для написания тестов для вашего Java-кода в выразительном и лаконичном Ruby. Здесь есть несколько полезных примеров с JtestR. Одним из преимуществ этого подхода является то, что насмешливые конкретные классы очень просты.

Я начал использовать mocks через JMock, но в конце концов перешел на EasyMock. EasyMock был просто, проще, и предоставлял синтаксис, который был более естественным. Я не переключался с тех пор.

Другие вопросы по тегам