-3

I have void function that does not return return anything with a if block inside. Is there a way while unit testing to verify if the "if" block is touched?

for example to test the "if" inside the following funtion:

public void doSomething(){
    if(someCondition){
        int foo = doThis();
    }
    // ---- 
    // remaining code
} 

private int doThis(){
    return 100;
}
vdk
  • 269
  • 4
  • 9
  • This seems like a pretty close overlap with [this other question here](http://stackoverflow.com/q/39975396/1426891). Marking as a duplicate, but please reopen if your topic is very different (but not if it's the same topic with your different specific case). – Jeff Bowman Oct 16 '16 at 22:34
  • I think it is pretty different. I just wanted to know if there is a way to do something like verify if doThis is called. – vdk Oct 17 '16 at 05:09
  • That’s the point, though: it's the same answers with same reasoning. Private methods and `if` blocks are implementation details, and though you can verify against the system under test using partial mocks, Mockito works best when treating the class as a unit and testing it's API and external collaboration (dependency interactions and return values) only. – Jeff Bowman Oct 17 '16 at 05:15
  • non of the answers in that other posts tells that this should not be done. – Timothy Truckle Oct 17 '16 at 06:55

2 Answers2

1

When doing UnitTest you want to test observable behavior, not code.

Observable behavior is either:

  • return values of (public) interface methods
  • interaction with other objects (dependencies)
  • changes of the object state (usually changes of getter results)

These are testet through the public interface of the class under test (CUT). these public interface does not nessessarrily mean public methods, but rather means methods which ar expected to be called by the code using the CUT.


In your case you want to test the state change of the object as a side effect when calling the method.

But the problem is that your code does not change the objects state, so nothing can be tested.

Technically you could raise the visibility of your the getter method and mock it with Mockito, but this is as useless as the whole code.

Amendment
I write this because the OP has an assignment to do it. I'd like to stress that this is not the way it should be done.


since the method to be observed is private you have 2 options:
  1. make the method to be observed visible to the test class. Then you can use regular Mockito functionality:

    /*ClassUnderTest CUT */ 
    public void doSomething(){
    if(someCondition){
        int foo = doThis();
    }
    // ---- 
    // remaining code
    } 
    
    /* package private, test class should be in same package  */ 
    int doThis(){
        return 100;
    }
    
    /* TestClass */
    @Test
    public void doSomething__conditionTrue__callesMemberMethod(){
       ClassUnderTest cut = Mockito.spy(new ClassUnderTest());
       // anything needed to make the condition true
    
       cut.doSomething();
    
       Mockito.verify(cut).doThis();
    }
    
    @Test
    public void doSomething__conditionFalse__doesNotCallMemberMethod(){
       ClassUnderTest cut = Mockito.spy(new ClassUnderTest());
       // anything needed to make the condition false
    
       cut.doSomething();
    
       Mockito.verify(cut,never()).doThis();
    }
  2. use PowerMock(-ito)
    but PowerMockito changes the byte code of the CUT and therefore you arn't really testing your CUT. I strongly suggest not to use it unless you have to test legacy code which is untestable otherwise.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
1

If your method returns void, that means that the only work it could possibly do is produce side effects. And thats what you REALY want to test.

  1. You set up external state
  2. You run the method under test
  3. You check that state changed as you'd expect it to change.

Prepare external state for each execution path inside method under test and that will cover all possible outcomes of your code.

Alex
  • 7,460
  • 2
  • 40
  • 51
  • I understood that but is there a way to even do something like verify if doThis was called ? – vdk Oct 17 '16 at 05:07
  • 1
    @visheshkamdar concrete class implementation shouldn't be tested, you want to test the method behavior (WHAT this method do) and not the implementation (HOW this method is doing it). Because implementation may change and you want the test to stay relevant. – Alex Oct 17 '16 at 05:15
  • I was looking at it the wrong way. Thanks SimY4 – vdk Oct 17 '16 at 11:07