Unit test per il metodo di salvataggio del repository JPA in Spring Boot

Aug 22 2020

Puoi dirmi come dovrei scrivere unit test per questo codice usando Mockito e JUnit? StudentRepository è un'interfaccia che estende JPA Repository.

public class StudentService {
    @Autowired
    StudentRepository studentRepository;
    
    public void saveStudentDetails(StudentModel student) {
        Student stud = new Student();
        stud.setStudentId(student.getStudentId());
        stud.setStudentName(student.getStudentName());
        studentRepository.save(stud);
    }
}

Risposte

3 Borsuk Aug 22 2020 at 00:25

Sono stato in questa stessa situazione un paio di giorni fa, e ho pensato qualcosa del genere.

@InjectMocks
StudentService studentService;
@Mock
StudentRepository studentRepository;

public void saveStudentDetailsTest(){
    //given
    StudentModel student = new StudentModel(Your parameters);
    //when
    studentService.saveStudentDetails(student);
    //then
    verify(studentRepository, times(1)).save(any());
}

Inoltre puoi usare ArgumentCaptor e controllare se l'oggetto che stai passando per salvare è quello che vuoi, e può assomigliare a questo

ArgumentCaptor<Student> captor = ArgumentCaptor.forClass(Student.class);
verify(studentRepository).save(captor.capture());
assertTrue(captor.getValue().getStudentName().equals(student.getStudentName()));
2 DanielJacob Aug 21 2020 at 23:37

Innanzitutto si desidera privilegiare l'iniezione del costruttore rispetto all'iniezione del campo. StudentService non dovrebbe funzionare senza la sua dipendenza da studentRepository. Dopo averlo modificato, puoi fare uno unit test usando Mockito, ad esempio. Passaggi da eseguire:

  1. Annota la classe con ExtendsWith(MockitoExtension.class)nel caso di junit 5 o @RunWith(MockitoJunit4ClassRunner.class)in caso di JUnit 4.
  2. creare uno StudentRepository Mock annotando una variabile di quel tipo con @Mock
  3. inserire il mock nel servizio annotando una variabile del servizio con @InjectMocks
  4. allora vuoi definire il comportamento beffardo. Puoi farlo con i mockitos quando costruisci. Sarà qualcosa di similewhen(studentRepository.myMethod()).thenReturn(MyCustomObject())
  5. chiamare il metodo di servizio
  6. affermare un determinato comportamento sul tuo servizio. Ad esempio, puoi utilizzare il costrutto di verifica di mockito per testare che studentRepository.save()viene chiamato una volta. Come nota a margine, un salvataggio non dovrebbe restituire void ma effettivamente restituire l'entità stessa.
avandeursen Aug 22 2020 at 01:03

Il tuo metodo fa due cose, rendendo difficile il test.

Il metodo crea prima un oggetto Student da StudentModel e quindi salva l'oggetto Student.

Puoi separare i due, estraendo la creazione di Student in un metodo separato (potrebbe essere nel tuo servizio, ma potrebbe anche essere nelle classi Student o StudentModel). Puoi testare quel metodo separatamente se lo desideri. Ciò evita la necessità di testarlo tramite un ArgumentCaptor.

Con ciò puoi seguire la risposta di Daniel o Borsuk per verificare che il tuo servizio richiami effettivamente il metodo di salvataggio del repository.