Not able to mock persistenceContext in spring boot test
10,041
Solution 1
You can do with with SpringRunner without @DataJpaTest
. This worked for me:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {DataRepository.class, EntityManager.class,
EntityManagerFactory.class})
public class DataRepositoryTest {
@MockBean
private EntityManager entityManager;
@MockBean
private EntityManagerFactory entityManagerFactory;
@Autowired
private DataRepository repository;
@Before
public void setup() {
Mockito.when(entityManagerFactory.createEntityManager()).thenReturn(entityManager);
}
@Test
public void resultTest() {
Query q = mock(Query.class);
when(q.setParameter(anyString(), any())).thenReturn(q);
when(q.getResultList()).thenReturn(createMockReponse());
when(entityManager.createQuery(anyString())).thenReturn(q);
Result r = repository.callQuery();
}
}
Solution 2
I've faced a similar problem and in order to solve it I had to use Springs ReflectionTestUtils in order to inject the mock:
@RunWith(SpringJUnit4ClassRunner.class)
public class RunRepositoryServiceTests {
private EntityManager entityManagerMock;
@Autowired
private RunRepositoryService runRepositoryService;
@Before
public void setUp () {
entityManagerMock = Mockito.mock(EntityManager.class);
ReflectionTestUtils.setField(runRepositoryService, "entityManager", entityManagerMock);
}
@Test
public void testFindBySearchCriteria() {
....
when(entityManagerMock.anyMethodToMock(anyObject())).thenReturn(...);
....
}
}
Solution 3
You can use JMockit to easily mock the dependency annotated with @PersistentContext
@RunWith(JMockit.class)
public class RunRepositoryServiceTests {
@Mocked EntityManager entityManager;
private RunRepositoryService runRepositoryService;
@Before
public void setup(){
runRepositoryService = new RunRepositoryService();
Deencapsulation.setField(runRepositoryService, entityManager); //because its a private field
}
@Test
public void testFindBySearchCriteria(@Mocked Query mockQuery) {
//random fake values for input args
String searchCriteria = "";
Integer offset = 1;
Integer limit = 2;
Integer userId = 1;
//fake object for output arg
List<Run> runList = new ArrayList<Run>();
new Expectations(){{
entityManager.someMethodToMock(argumentMatchers);
result = mockQuery;
times = 1;
//remaining expactations in your code, which will eventually return result
}};
//call method to test
List<Run> result = runRepositoryService.findBySearchCriteria(searchCriteria, offset, limit, userId);
//assertions
assertEquals(runList, result);
}
}
Comments
-
stallion almost 2 years
I am using spring-boot test with Mockito framework to test my application. One of the repository classes EntityManager as reference.
My class looks like below.
@Repository @Transactional @Slf4j public class SomeRepositoryService { @PersistenceContext private EntityManager entityManager; public List<Run> findBySearchCriteria(String searchCriteria,Integer offset,Integer limit,Integer userId) { //code } }
And test class looks like :
@RunWith(SpringRunner.class) @SpringBootTest public class RunRepositoryServiceTests { @MockBean EntityManager entityManager; @Autowired private RunRepositoryService runRepositoryService; @Test public void testFindBySearchCriteria() { //code to test } }
When i run this, i am getting
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.jpa.repository.support.DefaultJpaContext]: Constructor threw exception; nested exception is java.lang.NullPointerException Caused by: java.lang.NullPointerException: null at org.springframework.data.jpa.repository.support.DefaultJpaContext.<init>(DefaultJpaContext.java:53) ~[spring-data-jpa-2.0.9.RELEASE.jar:2.0.9.RELEASE]
can anyone let me know how to test this or solve this issue?
-
stallion over 5 yearsI tried it. It works, Thanks. But I will accept it if I don't get a Mockito based answer to this question.
-
stallion over 5 yearsTried with that.. I got this exception.. Caused by: java.lang.IllegalStateException: Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoConfigureTestDatabase.