JUnit – main difference: mockito and jmockit
This is what I found when I first tried to use jmockit I must admit that I found the jmockit document very concise about what it provides, so I may have missed some Nevertheless, this is what I know:
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()
I really want to be proved wrong here Jmockit claims to be able to do all this, and other ridicule frameworks have added a lot It doesn't look like this
@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()); }}; }
Such a statement
inOrder.verify(mockDatabase,times(2)).save((Article) notNull());
In mockito, there is no equivalent in jmockit, as shown in the above example
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; } };
Solution
In fact, by default, all mocking APIs will mock or kill every method of mocking type I think you confuse simulation (type) (full ridicule) with spy (obj) (partial ridicule)
In all cases, jmockit uses a simple API All this is described and illustrated in jmockit tutorial To prove it, you can see sample test suites (there are more tools removed from the newer version, but they can still be found in the old zip files), and maybe more jmockit integration tests (more than 1000 at present)
The spy equivalent of mockito is the "dynamic part" of jmockit Just pass the instance you want to partially emulate to the parameters of the expectations constructor If there is no expected record, the actual code will be executed when the execution code is executed BTW, mockito has a serious problem here (jmockit doesn't), because it always executes real code, even when it is called (...) or verified (...); Therefore, people must use doreturn (...) (...) to avoid the surprise of the peeping object
With regard to call validation, the jmockit validation API is more powerful than any other API For example:
new VerificationsInOrder() {{ // preceding invocations,if any mockDatabase.save((Article) withNotNull()); times = 2; // later invocations,if any }};