JUNITs are an easy and effective way to unit test your code. However when writing a JUNIT you need to ensure that the scope of test case remains within that class
only and does not go beyond it.
What this means is that say you have a class A which call a method of Class B from within it. Then ur unit test case should be limited to methods of Class A and
should not test method of Class B otherwise the test case will become an integration test. This can be achieved using a Mock framework such as Mockito and this is
where JUNITs become tricky as well.
only and does not go beyond it.
What this means is that say you have a class A which call a method of Class B from within it. Then ur unit test case should be limited to methods of Class A and
should not test method of Class B otherwise the test case will become an integration test. This can be achieved using a Mock framework such as Mockito and this is
where JUNITs become tricky as well.
I was trying to write JUNITs using Mockito for a simple case as mentioned above. Class code below:
Class to be tested:
public Class A {
public String parseEvent(String line) {
// some business logic
ClassB bObj = new ClassB();
String randomNum = bObj.getRandomNum().toString();
return line.append(randomNum);
}
}
Junit:
public class ATest {
@Test
public void testParseEvent() {
String inputLine= <some data>;
String expectedOutput =<some data>;
ClassB bObject = mock(ClassB.class);
when(bOject.getRandomNum()).thenReturn(2);
Class A aObject = new ClassA();
String result = aObject.parseEvent(inputLine);
Assert.assertArrayEquals(expectedOutput.getBytes(),result.getBytes());
}
}
This looked alright to me. I was trying to mock class B's method so as to return a predetermined number and then compare expected and actual output.
However despite trying above and many other approaches I could see that B's method was actually getting called instead of getting mocked.
After a lot of googling found out that the issue was not with Junit or Mocking but with the way Class A was written. Since it was instantiating object of Class B,
the mock object got lost and acutal instance got called. After refactoring Class A, Junit worked fine. Refactored code below:
public ClassA {
private ClassB obj=null;
public ClassA(ClassB obj) {
this.obj=obj;
}
public String parseEvent(String line) {
// some business logic
String randomNum = obj.getRandomNum().toString();
return line.append(randomNum);
}
}
After refactoring Class A's code, in my JUNIT i passed the mocked object of Class B when creating object of Class A. The mocking worked fine and Junit returned
expected result.
Happy Ending :)