Skip to content

Instantly share code, notes, and snippets.

@robsonlira
Created July 15, 2021 02:14
Show Gist options
  • Save robsonlira/b91217b529d1ab086ee0ca624bb91e83 to your computer and use it in GitHub Desktop.
Save robsonlira/b91217b529d1ab086ee0ca624bb91e83 to your computer and use it in GitHub Desktop.
Testes Unitários
public interface EntityMapper<D, E> {
E toEntity(D dto);
D toDto(E entity);
List<E> toEntity(List<D> dtoList);
List<D> toDto(List<E> entityList);
}
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String lastName;
@Column(nullable = false, unique = true)
private String cpf;
private LocalDate birthDate;
@OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private List<Phone> phones;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PersonDTO implements Serializable {
private Long id;
@NotEmpty
@Size(min = 2, max = 100)
private String firstName;
@NotEmpty
@Size(min = 2, max = 100)
private String lastName;
@NotEmpty
@CPF
private String cpf;
private String birthDate;
@Valid
@NotEmpty
private List<PhoneDTO> phones;
}
@Mapper(componentModel = "spring")
public interface PersonMapper extends EntityMapper<PersonDTO, Person> {
@Mapping(target = "birthDate", source = "birthDate", dateFormat = "dd-MM-yyyy")
Person toEntity(PersonDTO personDTO);
PersonDTO toDto(Person person);
}
@Service
@Slf4j
public class PersonService {
private final PersonRepository repository;
private final PersonMapper personMapper;
@Autowired
public PersonService(PersonRepository repository, PersonMapper personMapper) {
this.repository = repository;
this.personMapper = personMapper;
}
@Transactional
public MessageResponseDTO save(Person obj) {
log.debug("Saving...");
obj = repository.save(obj);
return createMessageResponse(obj.getId(), "Created person with ID ");
}
public List<PersonDTO> listAll() {
log.debug("Request to get list all People");
return personMapper.toDto(repository.findAll());
}
@Transactional(readOnly = true)
public Page<PersonDTO> findAll(Pageable pageable) {
log.debug("Request to get all People");
return repository.findAll(pageable).map(personMapper::toDto);
}
public Page<PersonDTO> findPage(Integer page, Integer linesPerPage, String orderBy, String direction) {
PageRequest pageRequest = PageRequest.of(page, linesPerPage, Direction.valueOf(direction), orderBy);
Page<Person> allObj = repository.findAll(pageRequest);
return allObj.map(obj -> personMapper.toDto(obj));
}
public PersonDTO findById(Long id) throws ObjectNotFoundException {
Person obj = verifyIfExists(id);
return personMapper.toDto(obj);
}
@Transactional(readOnly = true)
public Optional<PersonDTO> findOne(Long id) {
log.debug("Request to get Person : {}", id);
return repository.findById(id).map(personMapper::toDto);
}
public List<PersonDTO> findByFirstName(String name) {
log.debug("Request to get list all People with firstname");
return personMapper.toDto(repository.findByFirstName(name));
}
@Transactional
public MessageResponseDTO update(Long id, Person obj) throws ObjectNotFoundException {
verifyIfExists(id);
log.debug("Updating...");
Person updatedObj = repository.save(obj);
return createMessageResponse(updatedObj.getId(), "Updated person with ID ");
}
public void delete(Long id) throws ObjectNotFoundException {
verifyIfExists(id);
log.debug("Deleting...");
try {
repository.deleteById(id);
} catch (DataIntegrityViolationException e) {
throw new DataIntegrityException("Não é possível excluir um registro que possui movimentação");
}
}
private Person verifyIfExists(Long id) {
return repository.findById(id).orElseThrow(() -> new ObjectNotFoundException(
"Objeto não encontrado! Id: " + id + ", Tipo: " + Person.class.getName()));
}
public Person fromDTO(PersonDTO objDTO) {
return personMapper.toEntity(objDTO);
}
private MessageResponseDTO createMessageResponse(Long id, String message) {
return MessageResponseDTO.builder().message(message + id).build();
}
}
@ExtendWith(SpringExtension.class)
public class PersonServiceTest {
@InjectMocks
private PersonService service;
@Mock
private PersonRepository repositoryMock;
@BeforeEach
void setUp(){
Person expectedSavedPerson = PersonCreator.createValidPersonEntity();
List<Person> personList = Arrays.asList(PersonCreator.createValidPersonEntity());
PageImpl<Person> personPage = new PageImpl<>(Arrays.asList(PersonCreator.createValidPersonEntity()));
PageImpl<PersonDTO> personPageDTO = new PageImpl<>(Arrays.asList(PersonCreator.createValidPerson()));
List<PersonDTO> personDTOList = Arrays.asList(PersonCreator.createValidPersonDTO());
BDDMockito.when(repositoryMock.save(ArgumentMatchers.any(Person.class)))
.thenReturn(expectedSavedPerson);
BDDMockito.when(repositoryMock.findAll())
.thenReturn(personList);
BDDMockito.when(repositoryMock.findAll(ArgumentMatchers.any(PageRequest.class)))
.thenReturn(personPage);
BDDMockito.when(repositoryMock.findById(ArgumentMatchers.anyLong()))
.thenReturn(Optional.of(PersonCreator.createValidPersonEntity()));
}
@Test
@DisplayName("Create returns person when successful")
void create_ReturnsPerson_WhenSuccessful(){
Person person = PersonCreator.createValidPersonEntity();
Person expectedSavedPerson = PersonCreator.createValidPersonEntity();
MessageResponseDTO expectedSuccessMessage = createExpectedMessageResponse(expectedSavedPerson.getId());
MessageResponseDTO succesMessage = service.save(person);
Assertions.assertThat(succesMessage).isNotNull().isEqualTo(expectedSuccessMessage) ;
}
@Test
@DisplayName("ListAll returns list of person when successful")
void listAll_ReturnsListOfPerson_WhenSuccessful(){
String expectedName = PersonCreator.createValidPerson().getFirstName();
List<PersonDTO> persons = service.listAll();
//service.listAll() - Retorna List<PersonDTO>
Assertions.assertThat(persons)
.isNotNull()
.isNotEmpty()
.hasSize(1);
Assertions.assertThat(persons.get(0).getFirstName()).isEqualTo(expectedName);
}
@Test
@DisplayName("List returns list of person inside page object when successful")
void findPage_ReturnsPageOfPersonInsidePageObject_WhenSuccessful(){
String expectedName = PersonCreator.createValidPerson().getFirstName();
Page<PersonDTO> personPage = service.findPage(1, 1, "firstName", "ASC" );
Assertions.assertThat(personPage).isNotNull();
Assertions.assertThat(personPage.toList())
.isNotEmpty()
.hasSize(1);
Assertions.assertThat(personPage.toList().get(0).getFirstName()).isEqualTo(expectedName);
}
@Test
@DisplayName("FindById returns person when successful")
void findById_ReturnsPerson_WhenSuccessful(){
Long expectedId = PersonCreator.createValidPerson().getId();
PersonDTO person = service.findById(1L);
Assertions.assertThat(person).isNotNull();
Assertions.assertThat(person.getId()).isNotNull().isEqualTo(expectedId);
}
private MessageResponseDTO createExpectedMessageResponse(Long id) {
return MessageResponseDTO
.builder()
.message("Created person with ID " + id)
.build();
}
}
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Phone {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private PhoneType type;
@Column(nullable = false)
private String number;
}
@robsonlira
Copy link
Author

Estou tendo problemas no teste unitário de serviços, são quatro testes o único que esta funcionando é o de criação o que lista todos os registros retorna um NullPointerException,
Dando maiores detalhes estou usando DTO e a lib Mapstruct, o meu serviço que obtém todos os registros listAll() ele retorna uma lista List , eu observo o código e vejo que realmente da forma que esta o teste esta feito para justamente dar errado porque o mock do repositório retorna uma Lista de Person já o serviço retorna uma lista de PersonDTO então o mock diz qdo alguém solicitar do banco uma lista retorne a lista de Person e com certeza da o erro porque o método ele precisa retornar ....
List persons = service.listAll() // como dizer no Mock que eu preciso de uma lista de DTO?????

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment