Использую валидатор для проверки уникальности номера. В валидаторе автовайрю репозиторий для поиска по БД. Валидатор работает, но при запуске тестов валидатор не хочет автовайрить репозиторий и тесты не проходит. Как победить эту беду?
Сама сущность:
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Entity
@Table(name = "phone")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Phone implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@Column(name = "phone_number")
private Integer phoneNumber;
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getPhoneNumber() {
return phoneNumber;
}
public Phone phoneNumber(Integer phoneNumber) {
this.phoneNumber = phoneNumber;
return this;
}
public void setPhoneNumber(Integer phoneNumber) {
this.phoneNumber = phoneNumber;
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Phone phone = (Phone) o;
if (phone.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), phone.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public String toString() {
return "Phone{" +
"id=" + getId() +
", phoneNumber=" + getPhoneNumber() +
"}";
}
}
Валидатор:
import org.jhipster.blog.repository.PhoneRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
@Component
public class ContactNumberValidator implements ConstraintValidator<ContactNumberConstraint, Integer> {
@Autowired
private PhoneRepository repository;
@Override
public void initialize(ContactNumberConstraint phoneNumber) {
}
public ContactNumberValidator() {
}
@Override
public boolean isValid(Integer phoneNumber,
ConstraintValidatorContext cxt) {
Phone result = repository.findFirstByPhoneNumber(phoneNumber);
boolean b = result == null;
return b;
}
}
Контроллер в котором осуществляется валидация:
@RestController
@RequestMapping("/api")
public class PhoneResource {
private final Logger log = LoggerFactory.getLogger(PhoneResource.class);
private static final String ENTITY_NAME = "phone";
private final PhoneService phoneService;
public PhoneResource(PhoneService phoneService) {
this.phoneService = phoneService;
}
/**
* POST /phones : Create a new phone.
*
* @param phoneDTO the phoneDTO to create
* @return the ResponseEntity with status 201 (Created) and with body the new phoneDTO, or with status 400 (Bad Request) if the phone has already an ID
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
@PostMapping("/phones")
@Timed
public ResponseEntity<PhoneDTO> createPhone(@RequestBody @Valid PhoneDTO phoneDTO) throws URISyntaxException {
log.debug("REST request to save Phone : {}", phoneDTO);
if (phoneDTO.getId() != null) {
throw new BadRequestAlertException("A new phone cannot already have an ID", ENTITY_NAME, "idexists");
}
PhoneDTO result = phoneService.save(phoneDTO);
return ResponseEntity.created(new URI("/api/phones/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
.body(result);
}
...
}
Тест:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BlogApp.class)
public class PhoneResourceIntTest {
private static final Integer DEFAULT_PHONE_NUMBER = 1;
private static final Integer UPDATED_PHONE_NUMBER = 2;
@Autowired
private PhoneRepository phoneRepository;
@Autowired
private PhoneMapper phoneMapper;
@Autowired
private PhoneService phoneService;
@Autowired
private MappingJackson2HttpMessageConverter jacksonMessageConverter;
@Autowired
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
@Autowired
private ExceptionTranslator exceptionTranslator;
@Autowired
private EntityManager em;
private MockMvc restPhoneMockMvc;
private Phone phone;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
final PhoneResource phoneResource = new PhoneResource(phoneService);
this.restPhoneMockMvc = MockMvcBuilders.standaloneSetup(phoneResource)
.setCustomArgumentResolvers(pageableArgumentResolver)
.setControllerAdvice(exceptionTranslator)
.setConversionService(createFormattingConversionService())
.setMessageConverters(jacksonMessageConverter).build();
}
/**
* Create an entity for this test.
*
* This is a static method, as tests for other entities might also need it,
* if they test an entity which requires the current entity.
*/
public static Phone createEntity(EntityManager em) {
Phone phone = new Phone()
.phoneNumber(DEFAULT_PHONE_NUMBER);
return phone;
}
@Before
public void initTest() {
phone = createEntity(em);
}
@Test
@Transactional
public void createPhone() throws Exception {
int databaseSizeBeforeCreate = phoneRepository.findAll().size();
// Create the Phone
PhoneDTO phoneDTO = phoneMapper.toDto(phone);
restPhoneMockMvc.perform(post("/api/phones")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(phoneDTO)))
.andExpect(status().isCreated());
// Validate the Phone in the database
List<Phone> phoneList = phoneRepository.findAll();
assertThat(phoneList).hasSize(databaseSizeBeforeCreate + 1);
Phone testPhone = phoneList.get(phoneList.size() - 1);
assertThat(testPhone.getPhoneNumber()).isEqualTo(DEFAULT_PHONE_NUMBER);
}
...
}
С тестированием познакомился (в том числе и мокито) буквально на прошлой неделе, мне совсем не понятно для чего так тест "городить". Задача простая, проверить корректность метода ContactNumberValidator
#isValid().
Что для этого нужно ?
Я вижу это так:
ContactNumberValidator
, isValid()
метод правильно отработал нужен мок для PhoneRepository
, с тем чтобы можно было сделать стаббинг для метода findFirstByPhoneNumber
, который подсунет прямо в тесте же созданные объект - тут ничего не нужно вычитывать из базы.. Да, но чтобы иметь возможность использовать мок репозитория в тестовом методе (isValid
имеется в виду) придется добавить геттер для репозитория в ContactNumberValidator
, с помощью него можно будет сделать стаббинг геттера, который (репозиторий) будет создан в тесте в виде мока.
Phone result = getRepository().findFirstByPhoneNumber(phoneNumber);
Возможно, это некрасиво выглядит, но все выше описанное должно быть сведено к простой конструкции (это схема близка к тому что должно работать):
@Test
public void dummy() {
ContactNumberValidator validator = spy(ContactNumberValidator.class);
Integer phoneNumer = Integer.valueOf(12345);
ConstraintValidatorContext ctx = new ConstraintValidatorContext();
PhoneRepository repository = spy(PhoneRepository.class);
Phone phone = new Phone();
doReturn(repository).when(validator).getRepository();
doReturn(phone).when(repository).findFirstByPhoneNumber(anyInt());
bolean actual = validator.isValid(phoneNumer, ctx);
Assert.assertFalse(actual);
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как замечательно что есть такой форум на котором можно задавать вопросыПотому что голову уже сломал
Помогите подключиться к базе данных удаленнопробовал настроить сервер, но не могу понять как подключиться к нему удаленно
У менять есть кнопка Start, в ней я создаю объект и добавляю его для видимости (и это работает), есть другая кнопка newGame, по сути я там делаю тоже...
Есть клиент и сервер на Java RMIКлиент считывает текст с консоли через Scanner