Основное различие между: Mockito и JMockIt - PullRequest
10 голосов
/ 09 октября 2011

Это то, что я обнаружил в своих первых попытках использовать 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;
    }
};

Ответы [ 2 ]

9 голосов
/ 26 октября 2011

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

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

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

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

new VerificationsInOrder() {{
    // preceding invocations, if any
    mockDatabase.save((Article) withNotNull()); times = 2;
    // later invocations, if any
}};
6 голосов
/ 10 октября 2011

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

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

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

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

...