I 've trying to test a service which uses hibernate envers to perform a rollback. Everything is working fine but the test is driving me mad.
This is the beginning of the service:
@Slf4j
@AllArgsConstructor
@Service
public class ObjectRollbackServiceImpl implements ObjectRollbackService {
@Autowired
private EntityManager entityManager;
@Autowired private ObjectRollbackRepository objectRollbackRepository;
private void restorePreviousVersionOfObject(Long id, Boolean isDelete) {
AuditReader auditReader = AuditReaderFactory.get(entityManager);
List<Number> revNumbers = auditReader.getRevisions(ObjectEntity.class, id);
And this is the test:
class ObjectRollbackServiceTests {
private static final Long objectId = 1L;
@InjectMocks
ObjectRollbackServiceImpl objectRollbackServiceImpl;
@Mock
ObjectRollbackRepository objectRollbackRepository;
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
@Mock
AuditReader auditReader;
@BeforeEach
void setUp() throws Exception {
MockitoAnnotations.openMocks(this);
}
@Test
void testRestorePreviousVersionOfEditedObjectOk() {
ObjectEntity object = ObjectEntity.builder().build();
List<Number> listRevisions = Lists.newArrayList();
listRevisions.add(1);
when(auditReader.getRevisions(any(), any(Long.class))).thenReturn(listRevisions);
when(auditReader.find(any(), any(Long.class), any(Number.class))).thenReturn(object);
when(objectRollbackRepository.findById(any(Long.class))).thenReturn(Optional.of(object));
when(objectRollbackRepository.saveAndFlush(any(ObjectEntity.class))).thenReturn(object);
doNothing().when(objectRollbackRepository).updateAuditDates(any(ZonedDateTime.class)
, any(Integer.class)
, any(AuditorBO.class)
, any(Long.class));
doNothing().when(objectRollbackRepository).deleteRevisionsNotEqualsToCurrentAndPrevious(any(Integer.class), any(Long.class));
assertDoesNotThrow(() -> objectRollbackServiceImpl.restorePreviousVersionOfEditedObject(1L));
}
}
So the problem is that entityManager is null when trying to execute this line:
AuditReader auditReader = AuditReaderFactory.get(entityManager);
What am I missing?
CodePudding user response:
you autowired the entityManager. when you apply @PersistenceUnit on entityManager fields it tries to create the real instance. But we need a mock instance. Apply @Mock and try.
CodePudding user response:
You are using @AllArgsConstructor
so it is creating behind the scenes a constructor with the following signature:
ObjectRollbackServiceImpl(EntityManager entityManager,
ObjectRollbackRepository objectRollbackRepository)
So when you use @InjectMocks
it expects you mock the parameters of the constructor:
@Mock
EntityManager entityManager;
@Mock
ObjectRollbackRepository objectRollbackRepository;
@InjectMocks
ObjectRollbackServiceImpl objectRollbackServiceImpl;