How can I know if a method was invoked on the unit under test?
I’m writing a new class ( Derived ), in TDD, using mockito and I have the following case: Class Base:
public abstract class Base < //. protected final T baseCreate(T entity)< // implementation >>
public class Derived extends Base < //. public MyObject create(MyObject entity)< baseCreate(entity); //This is what I want the implementation to be >>
When I came to write a test the will force me to invoke the baseCreate method — I failed to understand how to do that. Is there a way, using mockito, to verify that the create(. ) method in Derived invokes the baseCreate(. ) method in the Base class? Thanks.
3 Answers 3
Unit tests are to test the behavior of the class, not its implementation. So you should not concern yourself with whther the Base ‘s baseCreate() is called explicitly, rather wheter calling Derived ‘s cerate() does exactly as you expect from an external observer’s perspective
Hi Attila, Thanks for the answer, but since I’m writing in TDD, I need to write the implementation of the Derived class only when a test fails. So, in that case, the implementation can also be return null; and the test will still pass.
So you need to test for a condition that is true when the Base.baseCreate() is called and false when it is not
Attila is right for most cases. What you want to test is that create actually does what you think it should do, not how it does it. The case you have here sounds like, «I already know that baseCreate does what I want it to do, so I don’t want to re-test that, just that it gets called.» This could be the case, but if so, then your superclass is really more of a collaborator. It’s part of the reason to favor delegation over inheritance. Nonetheless, sometimes it is difficult to go back and change that design decision, so you have to test what you have.
You should still favor just checking that «create» does what you want it to do on the whole, but you might have a case where baseCreate is really doing a lot of stuff that requires a lot of set up of collaborators and such which makes it difficult and brittle to test. In that case, you would want to use a «spy». A spy wraps a «real» object and delegates to the real method calls unless you specifically create another expectation.
If you could make baseCreate public, you could use Mockito like this:
@RunWith(MockitoJUnitRunner.class) // We prepare PartialMockClass for test because it's final or we need to mock private or static methods public class YourTestCase < @Spy private Derived classUnderTest = new Derived(); @Test public void privatePartialMockingWithPowerMock() < MyObject myObject = new MyObject(); when(classUnderTest.baseCreate(myObject)).thenReturn(myObject); // execute your test classUnderTest.create(myObject); verify(classUnderTest).baseCreate(myObject); >>
If you can’t make baseCreate public, I think you could use PowerMock. It lets you verify private methods, but I don’t think there would be any reason it couldn’t do protected methods, too.
@RunWith(PowerMockRunner.class) // We prepare PartialMockClass for test because it's final or we need to mock private or static methods @PrepareForTest(Derived.class) public class YourTestCase < @Test public void testCreate() < Derived classUnderTest = PowerMockito.spy(new Derived()); MyObject myObject = new MyObject(); // use PowerMockito to set up your expectation PowerMockito.doReturn(myObject).when(classUnderTest, "baseCreate", myObject); // execute your test classUnderTest.create(myObject); // Use PowerMockito.verify() to verify result PowerMockito.verifyPrivate(classUnderTest).invoke("baseCreate", myObject); >>
JUnit — test that a method has been called
I’m new to unit testing, and I’m trying to test that a method has been called. The method in question doesn’t return anything.
public void example (boolean foo) < if (foo) < processFoo(foo); >else if (foo==false) < processSomethingElse(foo); >>
I want to be able to test that the processFoo method is being called, but I don’t know how to do that. If mocking is required, then I have to use JMockit . Thanks!
You can create spy of a class under the test throwing some exception when processFoo method is being called. If you catch this exception, everything is ok, otherwise this method hadn’t been called.
Duncan, I know, this doesn’t exactly match the code I’m using (which is for work so I can’t directly copy and paste) it’s actually not a boolean, but this seemed like the easiest way to explain the question 🙂
4 Answers 4
Sorry I’m a little late to the party, but I have a couple of ideas for you.
First, you mention that one option is to use JMockit—that’s great as it gives you a lot of flexibility. If you use JMockit, then the visibility of your processFoo() method doesn’t much matter. Let’s see what that might look like:
public class Subject < public void example (boolean foo) < if (foo) < processFoo(foo); >else if (foo==false) < processSomethingElse(foo); >> private void processFoo(boolean b) < System.out.println("b = " + b); >private void processSomethingElse(boolean bb) < System.out.println("bb b = " + b); >private void processSomethingElse(boolean bb) < System.out.println("bb mt24"> )" data-controller="se-share-sheet" data-se-share-sheet-title="Share a link to this answer" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="answer" data-se-share-sheet-social="facebook twitter devto" data-se-share-sheet-location="2" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f3.0%2f" data-se-share-sheet-license-name="CC BY-SA 3.0" data-s-popover-placement="bottom-start">Share )" title="">Improve this answer answered Dec 23, 2014 at 20:58 unigeekunigeek 2,646 27 silver badges 27 bronze badges