Метод put из Mockmvc всегда возвращает статус 204 - PullRequest
0 голосов
/ 13 июня 2018

Я пишу контрольные примеры для моего репозитория остатков данных:

@RepositoryRestResource(collectionResourceRel = "teams", path = "teams")
public interface TeamRepo extends JpaRepository<Team, Long> {}

Все в порядке, но когда я обновляю недопустимый ресурс методом put, mockmvc всегда возвращает статус 204. Код выглядит следующим образом:

@Test
@Transactional
public void updateInvalidResourceFail_thenReturn400() throws Exception {
    final Team resource = createNewResource();
    invalidate(resource); // Some properties violate uniqueness constraints
    final String resourceAsString = marshaller.encode(resource);
    mvc.perform(
            put("/api/teams/1")
                    .contentType(marshaller.getMime())
                    .content(resourceAsString)
    ).andExpect(status().isBadRequest()).andDo(print());

    TestTransaction.flagForCommit();
    TestTransaction.end();
}

mockmvc:

protected MockMvc mvc;
@Autowired
private WebApplicationContext context;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);

    mvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity())
            .build();
}

ошибка:

java.lang.AssertionError: Status 
Expected :400
Actual   :204

Однако PostMan возвращает правильный результат с теми же недействительными данными:

{
"status": "BAD_REQUEST",
"instant": "2018-06-13T06:16:20.975Z",
"message": "Database error, Constraint  Violation",
"debug": "could not execute statement"
}

Когда я изменяю статус ожидания на 204,

.andExpect(status().isNoContent()).andDo(print());

я получаю ожидаемое исключение:

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

причина:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: #23000

Это похоже на этот mockmvcвсегда возвращайте 204. Куда я иду не так?

Редактировать

Команда сущности:

@Entity
@ToString
@DynamicUpdate
@DynamicInsert
@Table(name = "bus_team", schema = "test", uniqueConstraints = {
    @UniqueConstraint(columnNames = {
            "name"
    })
})
public class Team{
    private Long id;
    private String name;
    private String description;
    private String division;
    // ... getter, setter
 }

Метод недействителен (команда команды):

void invalidate(Team team){
    team.setName("name already exists");
}

1 Ответ

0 голосов
/ 14 июня 2018

Я думаю, что есть две потенциальные причины такого поведения.

Во-первых, вы делаете PUT, а не пытаетесь создать новый объект в базе данных, а просто обновляетесуществующий объект с измененными значениями.Поэтому ограничение уникальности не нарушается, поскольку предыдущее значение просто перезаписывается новым.

Вторая возможная причина - при запуске теста с помощью mockmvc он будет использовать данные в памятиисточник.Когда вы запускаете тест с Postman, он предположительно использует другой источник данных (в зависимости от вашей конфигурации).Таким образом, тесты mockmvc начнутся с новой базы данных, содержащей разные данные из вашей тестовой базы данных Postman.Поэтому тест, возможно, не вызовет нарушение ограничения, если только вы не убедитесь, что в базе данных в памяти уже есть нужные данные, используемые тестом mockmvc.Надеюсь, это имеет смысл!Вы уверены, что источник данных в памяти содержит данные, необходимые для запуска ожидаемого ограничения целостности?

...