Im not new to mockito, but this time I found an interesting case during my work. I hope you can help me out with it.
I need to inject mock to change certain method behaviour during the test. The problem is, the bean structure is nested, and this bean is inside other beans, not accessible from test method. My code looks like this:
@Component
class TestedService {
@Autowired
NestedService nestedService;
}
@Component
class NestedService {
@Autowired
MoreNestedService moreNestedService;
}
@Component
class MoreNestedService {
@Autowired
NestedDao nestedDao;
}
@Component
class NestedDao {
public int method(){
//typical dao method, details omitted
};
}
So in my test I would like the call NestedDao.method to return mocked answer.
class Test {
@Mock
NestedDao nestedDao;
@InjectMocks
TestedService testedSevice;
@Test
void test() {
Mockito.when(nestedDao.method()).thenReturn(1);
//data preparation omitted
testedSevice.callNestedServiceThatCallsNestedDaoMethod();
//assertions omitted
}
}
I have tried to do a initMocks:
@BeforeMethod
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
Also to add annotation upon my test class:
@RunWith(MockitoJUnitRunner.class)
Always getting nullpointers or wrong answer from method (not mocked).
I guess it's this nested calls fault, making it impossible to mock this Dao. Also Ive read that @InjectMocks only would work with setters or constructor injection, which im missing (just @Autowire on private fields), but it didn't worked when I tried.
Any guess what am I missing? ;)
when(nestedService.callDaoMethod()).return("stuff which the dao should return")
instead. – TomTestedService
and not implementation details ofNestedService
and its nested dependencies. For example your classMoreNestedService
... this class doesn't even need to be mentioned in the test. You only mockTestedService
and tell that mock what to return on a certain method call. That this method may call nested methods "in real life" doesn't matter right now. – Tom