Reputation: 914
I have an abstract method checkStatus()
which has implementations in Checker.java class. But when I execute the Junit test case on abstract class method validate()
that in-turn calls checkStatus()
, fails due to missing spring dependency in Checker.java class.
Details provided below.
Abstract class:
public abstract class MyAbstractClass
{
protected abstract boolean checkStatus();
public boolean validate()
{
//Some code
return checkStatus();
}
}
Implementation class:
public class Checker extends MyAbstractClass
{
@Autowired
private StatusHelper helper;
public void setHelper(StatusHelper helper){
this.helper = helper;
}
@Override
public boolean checkStatus() throws Exception{
if(null == helper){
throw new Exception("Helper is null");
}
return helper.validateStatus();
}
}
JUnit test:
class AbstractClassTest
{
MyAbstractClass absClass = Mockito.mock(Checker.class, Mockito.CALLS_REAL_METHODS);
@Test
public void testStatusOfChecker()throws Exception {
boolean status = absClass.validate();
assertEquals(status, true);
}
}
I believe I can inject the helper object manually like the following
Checker check = mock(Checker.class);
StatusHelper helper = mock(StatusHelper.class);
check.setHelper(helper);
but the problem here is, I cannot inject directly to absClass
object as the setHelper()
is not inherited.
I can instead write test case directly to subclass, but I needed this way to test some other functionality in validate()
method of abstract class.
Can someone help me how to set helper object to the sub class or is there different way to do it in Junit? Any help or links that contain relevant info is highly appreciable. Thanks,
Upvotes: 0
Views: 858
Reputation: 24510
The only way to test an abstract class is by testing an implementation (which could be an anonymous class).
public class AbstractClassTest {
@Test
public void testStatusOfChecker() throws Exception {
MyAbstractClass object = new MyAbstractClass() {
protected boolean checkStatus() {
return true; //this is the place to provide the expected value
}
}
boolean status = absClass.validate();
assertEquals(status, true);
}
}
If you want to test the Checker
implementation then you must not mock it.
public class CheckerTest {
@Test
public void test() {
StatusHelper helper = mock(StatusHelper.class);
Checker checker = new Checker();
checker.setHelper(helper);
when(helper.validate()).thenReturn(true);
boolean status = checker.validate();
assertEquals(status, true);
}
}
By the way I strongly recommend to use constructor injection (see Why field injection is evil). The test would then look like this
public class CheckerTest {
@Test
public void test() {
StatusHelper helper = mock(StatusHelper.class);
Checker checker = new Checker(helper);
when(helper.validate()).thenReturn(true);
boolean status = checker.validate();
assertEquals(status, true);
}
}
Upvotes: 2