3

For my application I have a function handler like that:

class MyFoo {

    private MyFoo2 myFoo2 = new MyFoo2();

    public void handler(Object o) {

        if (o.getName().equals("Name1")) {
            myFoo2.doSomeStuff1(o);
        } else if (o.getName().equals("Name2")) {
            myFoo2.doSomeStuff2(o);
        }
    }
}

class MyFoo2{

    List<Object> objectList=new ArrayList<>();

    public void doSomeStuff1(Object o){
        //prepare Object o I
        objectList.add(o);
    }

    public void doSomeStuff2(Object o){
        //prepare Object o II
        objectList.add(o);
    }

    public getObjectList(){
        return objectList;
    }
}

Now I want to test my function handler with JUnit. To test it, should i have to get the objectList from my MyFoo2 and check the entry or is there another way to check a function like that? What is here a good way for testing? Are test like that unnecessary?

JavaNullPointer
  • 1,199
  • 5
  • 21
  • 43
  • 1
    Note: Comparing strings with `==` does not do what you think it does in Java. See: [How do I compare strings in Java?](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – Jesper Jul 15 '16 at 10:48
  • @Jesper: Thanks for that hint – JavaNullPointer Jul 15 '16 at 10:51
  • 1
    Side note: if you are interested in learning stuff ... consider getting rid of such if statements. Actually, in good OO designs, you dont do "if" ... but you use polymorphism. See https://www.youtube.com/watch?v=4F72VULWFvc&list=PLD0011D00849E1B79&index=4 – GhostCat Jul 15 '16 at 13:49

4 Answers4

2

Since you ara talking about unit test, the correct way to test is should be without MyFoo2

You are testing MyFoo1, so you can mock MyFoo2 and use it just to verify the execution happens. something like:

public class MyFoo1Test {

  @Mock private MyFoo2 mockMyFoo2;

  @InjectMocks
  private MyFoo1 myFoo1 = new MyFoo1();

  @Test
  public void testHandlerName1() {
    Object o = new Object("Name1"); 
    myFoo1.handler(o);
    verify(myFoo2).doSomeStuff1(o);
  }

  @Test
  public void testHandlerName2() {
    Object o = new Object("Name2"); 
    myFoo1.handler(o);
    verify(myFoo2).doSomeStuff2(o);
  }

  @Test
  public void testHandlerOtherName() {
    Object o = new Object("OtherName"); 
    myFoo1.handler(o);
    verifyZeroInteractions(myFoo2);
  }

}

Unit tests for MyFoo2 should be done seperatly, and in there you should test the doSomeStuff methods

Nir Levy
  • 12,750
  • 3
  • 21
  • 38
  • In your implementation, the myFoo2 mock is not associated to the myFoo1. So the mock cannot work. Besides, why coupling the question to a specific mocking implementation ? Here mockito. – davidxxx Jul 15 '16 at 11:01
  • It 's I said. This code cannot work. You must associate the MyFoo2 instance to the MyFoo1 instance. You can use constructor, setter, or reflections... – davidxxx Jul 15 '16 at 15:14
2

In your case, if I would do a "real" unit test, i would isolate myFoo2 instance by injecting a mock inside and in my JUnit assertion, i would assert that myFoo2.doSomeStuff1(o) is called when the good o.getName() is present.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
1

I think the answer lies in your question itself :

Should i have to get the objectList from my MyFoo2 and check the entry?

Does that mean you need to test the method doSomeStuff1 of your MyFoo2 class in it's own unit test?

Well yes, you create unit test for your class MyFoo2 and perform all tests related to that class in it's own unit test class, rather than testing it as part of some another test class.

UPDATE :

When unit testing your handler method, you should only test that it calls appropriate methods on myFoo2 object (doSomeStuff1 or doSomeStuff2) depending on test. You could use mocking util like mockito for myFoo2 and verify that doSomeStuff1 or doSomeStuff1 is called on that mock object.

Abubakkar
  • 15,488
  • 8
  • 55
  • 83
1

Yes. Do add unit test case for the handler method also. To ensure the if-else conditions are covered.

Also adding to the comment by Jesper, 1) always do a null pointer check before getting values from an object during comparison or 2) just move that to right side of the comparison .

Ex.: "Name1".equals(o.getName())

Please consider this as comment since I don't yet have access to provide comments