Created
July 15, 2021 02:14
-
-
Save robsonlira/b91217b529d1ab086ee0ca624bb91e83 to your computer and use it in GitHub Desktop.
Testes Unitários
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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?????