主要区别:Mockito和JMockIt

时间:2011-10-08 22:14:38

标签: junit mocking 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;
    }
};

2 个答案:

答案 0 :(得分:9)

实际上,默认情况下,所有模拟API都会模拟或删除模拟类型中的每个方法。我认为您将mock(type)(“完整”模拟)与spy(obj)混淆了(部分模拟)。

JMockit可以做到这一切,在每种情况下使用简单的API。通过示例在JMockit Tutorial中对所有内容进行了描述。 为了证明,您可以看到sample test suites(还有更多已从工具包的较新版本中删除,但仍可在old zip files中找到),或许多JMockit集成测试(在目前一千

相当于Mockito的spy是JMockit中的“动态部分模拟”。只需将您想要部分模拟的实例作为参数传递给Expectations构造函数。如果没有记录预期,则在执行测试代码时将执行实际代码。顺便说一句,Mockito在这里有一个严重的问题(JMockit没有),因为总是执行实际代码,即使它在when(...)verify(...)内调用;因此,人们必须使用doReturn(...).when(...)来避免对间谍物体的意外。

关于调用的验证,JMockit Verifications API比其他任何API都强大。例如:

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

答案 1 :(得分:6)

Mockito是一个比JMockIT更老的库,所以你可以期待它有many more features。如果您想查看一些记录不太完整的功能,请阅读发布列表。 JMockIT的作者已经制作了a matrix of features,他们错过了其他框架所做的每一件事,而他们没有做错,并且犯了几个错误(例如,Mockito可以做严格的模拟和订购)。

Mockito也被编写为启用单元级BDD。这通常意味着,如果您的测试提供了如何使用代码的良好示例,并且如果您的代码可爱且分离且设计良好,那么您将不会需要 JMockIT提供的所有恶作剧。在开源中最困难的事情之一是对许多从长远来看没有帮助的请求说“不”。

比较MockitoJMockIT首页上的示例,看看真正的区别。这不是关于你测试的内容,而是关于你的测试记录和描述课堂行为的程度。

利益声明: Szczepan和我在撰写Mockito初稿时处于同一个项目之后,看到我们中的一些人推出了我们自己的存根类而不是使用现有的模拟框架时间。所以我觉得他为我写了这一切,并且完全有偏见。谢谢Szczepan。