Основное различие между: Mockito и JMockIt

Это то, что я нашел из своих первоначальных попыток использовать JMockIt. Должен признать, что я нашел документацию JMockIt очень тонкой для того, что она предоставляет, и, следовательно, я мог что-то пропустить. Тем не менее, это то, что я понял:

Mockito: List a = mock(ArrayList.class) does not stub out all methods
of List.class by default. a.add("foo") is going to do the usual thing
of adding the element to the list.

JMockIt: @Mocked ArrayList<String> a;
It stubs out all the methods of a by default. So, now a.add("foo")
is not going to work.

This seems like a very big limitation to me in JMockIt.
How do I express the fact that I only want you to give me statistics
of add() method and not replace the function implementation itself
What if I just want JMockIt to count the number of times method  add()
was called, but leave the implementation of add() as is?

I a unable to express this in JMockIt. However, it seems I can do this
in Mockito using spy()

Я действительно хочу быть здесь ошибочным. JMockit утверждает, что он может делать все, что другие издевательские рамки делают плюс намного больше. Здесь не похоже, что здесь

@Test
public void shouldPersistRecalculatedArticle()
{
  Article articleOne = new Article();
  Article articleTwo = new Article();

  when(mockCalculator.countNumberOfRelatedArticles(articleOne)).thenReturn(1);
  when(mockCalculator.countNumberOfRelatedArticles(articleTwo)).thenReturn(12);
  when(mockDatabase.getArticlesFor("Guardian")).thenReturn(asList(articleOne, articleTwo));

  articleManager.updateRelatedArticlesCounters("Guardian");

  InOrder inOrder = inOrder(mockDatabase, mockCalculator);
  inOrder.verify(mockCalculator).countNumberOfRelatedArticles(isA(Article.class));
  inOrder.verify(mockDatabase, times(2)).save((Article) notNull());
}



@Test
public void shouldPersistRecalculatedArticle()
{
  final Article articleOne = new Article();
  final Article articleTwo = new Article();

  new Expectations() {{
     mockCalculator.countNumberOfRelatedArticles(articleOne); result = 1;
     mockCalculator.countNumberOfRelatedArticles(articleTwo); result = 12;
     mockDatabase.getArticlesFor("Guardian"); result = asList(articleOne, articleTwo);
  }};

  articleManager.updateRelatedArticlesCounters("Guardian");

  new VerificationsInOrder(2) {{
     mockCalculator.countNumberOfRelatedArticles(withInstanceOf(Article.class));
     mockDatabase.save((Article) withNotNull());
  }};
}

Заявление вроде этого

inOrder.verify(mockDatabase, times(2)).save((Article) notNull());

в Mockito, не имеет эквивалента в JMockIt, как вы можете видеть из приведенного выше примера

new NonStrictExpectations(Foo.class, Bar.class, zooObj)
{
    {
        // don't call zooObj.method1() here
        // Otherwise it will get stubbed out
    }
};


new Verifications()
{
    {
        zooObj.method1(); times = N;
    }
};

Ответ 1

Фактически, все насмешливые API-интерфейсы издеваются над любым методом в стиле mocked по умолчанию. Я думаю, вы путаете mock(type) ( "полный" насмешливый) с spy(obj) (частичным насмешкой).

JMockit делает все это, используя простой API в каждом случае. Все это описано с примерами в JMockit Tutorial. Для доказательства вы можете увидеть примеры тестовых наборов (есть еще много, которые были удалены из более новых выпусков инструментария, но все равно могут быть найденные в старые zip файлы), или многие интеграционные тесты JMockit (более одной тысячи в настоящее время).

Эквивалент Mockito spy - это "динамическое частичное издевательство" в JMockit. Просто передайте экземпляры, которые вы хотите частично высмеять как аргументы конструктора Expectations. Если ожиданий не будет зафиксировано, реальный код будет выполнен, когда выполняется проверка кода. Кстати, Mockito имеет здесь серьезную проблему (чего JMockit не делает), потому что он всегда выполняет реальный код, даже если он вызывает внутри when(...) или verify(...); из-за этого люди должны использовать doReturn(...).when(...), чтобы избежать сюрпризов на шпионских объектах.

Что касается проверки вызовов, API проверки JMockit значительно более эффективен, чем любой другой. Например:

new VerificationsInOrder() {{
    // preceding invocations, if any
    mockDatabase.save((Article) withNotNull()); times = 2;
    // later invocations, if any
}};

Ответ 2

Mockito гораздо более старая библиотека, чем JMockIT, поэтому вы можете ожидать, что она будет еще много функций. Прочитайте список выпусков, если вы хотите увидеть некоторые из менее хорошо документированных функций. Авторы JMockIT произвели матрицу функций, в которой они пропустили все, что делают другие фреймворки, которых они не делают, и получили несколько ошибок ( например, Мокито может выполнять строгие макеты и заказывать).

Mockito также был написан для включения BDD на уровне единицы. Это обычно означает, что если ваши тесты дают хороший пример того, как использовать код, и если ваш код прекрасен и развязан и хорошо разработан, вам не понадобятся все махинации, которые предоставляет JMockIT. Одна из самых сложных вещей в Open Source - "нет" для многих запросов, которые не помогают в долгосрочной перспективе.

Сравните примеры на первых страницах Mockito и JMockIT, чтобы увидеть реальную разницу. Это не о том, что вы тестируете, о том, насколько хорошо ваши документы теста и описывают поведение класса.

Декларация интереса: Мы с Щепаном были в одном проекте, когда он написал первый проект Мокито, увидев, что некоторые из нас разворачивают наши собственные классы-заглушки, а не используют существующие издевательские рамки время. Поэтому я чувствую, что он все это написал для меня, и я полностью предвзято. Спасибо Щепан.