Issue
What's the standard way of accessing/setting a private field in a Java-EE-Bean for Mockito testing? The test is as follows, but the MyDao-field is null, of course, if I run the (Mockito-) test. A NullPointerException is thrown for MyDao.
But I don't want to use Reflection - is there another way to do it or is the architecture of the service bad?
The class to test:
@Stateless
public class MyServiceImpl extends AbstractService {
@Inject
private MyDao myDao;
public MyEntity findByIdOrThrow( final long id ) throws Exception {
if ( id > 0 ) {
final MyEntity entity = myDao.findById( id );
if ( entity == null ) {
throw new Exception( );
} else {
return entity;
}
} else {
throw new Exception( );
}
}
The test class:
public class MyServiceImplTest {
private MyServiceImpl myServiceImpl;
@BeforeEach
public void setup() {
myServiceImpl = new ServiceServiceImpl();
}
@Test
public void findByIdOrThrow() throws Exception {
Long id = 1L;
when( myServiceImpl.findByIdOrThrow( id ) ).thenReturn( new MyEntity() );
}}
Test class updated:
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.junit.MockitoJUnitRunner;
import de.myapp.dao.MyDao;
import de.myapp.entity.MyEntity;
@RunWith( MockitoJUnitRunner.class )
public class ServiceServiceImplTest {
@Mock
public MyDao myDao;
@InjectMocks
public MyServiceImpl myServiceImpl;
@Test
public void findByIdOrThrow() throws Exception {
final Long id = 1L;
when( myServiceImpl.findByIdOrThrow( id ) ).thenReturn( new MyEntity() );
}
}
Solution
I'm supposing that MyDao
is an interface. You have to do the following in your test class:
@Mock
private MyDao myDao;
@InjectMocks
private MyServiceImpl myServiceImpl;
and remove the @BeforeEach
method. In this way you will inject a mock of your dao in te class. Using Mockito.when
you will setup the dao-mock correctly to simulate your real dao. Do not forget to change the test declaration as it follows:
@RunWith(MockitoJUnitRunner.class)
public class MyServiceImplTest
If you are using JUnit 5 the test class declaration should be the following:
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
In this last case probably you can omit the @RunWith
, but I am not sure.
Answered By - Lorelorelore