@MockMvc does not work with validation annotated with @Valid

雨燕双飞 提交于 2019-12-12 16:33:06

问题


None of these solutions helped here: Spring mockMvc doesn't consider validation in my test. Added all of these dependencies, nothing helps.

I use Spring Boot 2.1.2, pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.2.RELEASE</version>
</parent>
<properties>
    <java.version>1.8</java.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-hateoas</artifactId>
    </dependency>

    <!-- Testing -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.github.springtestdbunit</groupId>
        <artifactId>spring-test-dbunit</artifactId>
        <version>1.3.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.dbunit</groupId>
        <artifactId>dbunit</artifactId>
        <version>2.5.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.jcabi</groupId>
        <artifactId>jcabi-matchers</artifactId>
        <version>1.3</version>
        <scope>test</scope>
    </dependency>

</dependencies>

I use standard hibernate validation '@NotNull':

@Entity
@Table(name="employee")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Employee  {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    @NotNull(message = "Please provide name")
    @Column(name = "name")
    private String name;

    @Column(name = "role")
    private String role;

    public Employee() {}

    public Employee(String name, String role) {
        this.name = name;
        this.role = role;
    }
}

@RestController
@RequestMapping(EmployeeController.PATH)
public class EmployeeController {

    public final static String PATH = "/employees";

    @Autowired
    private EmployeeService service;

    @PostMapping("")
    public Employee newEmployee(@RequestBody @Valid Employee newEmployee) {
        return service.save(newEmployee);
    }
}

@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository repository;

    public Employee save(Employee entity) {
        return getRepository().save(entity);
    }
}

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

}

Then I test my controller:

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
@DatabaseSetup("/employee.xml")
@TestExecutionListeners({
        TransactionalTestExecutionListener.class,
        DependencyInjectionTestExecutionListener.class,
        DbUnitTestExecutionListener.class
})
public class EmployeeControllerWebApplicationTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;
    private static String employeeRouteWithParam = EmployeeController.PATH + "/{id}";

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders
                .webAppContextSetup(context)
                .build();
    }

    @Test
    public void create_WithoutName_ShouldThrowException() throws Exception {
        String role = "admin";
        Employee expectedEmployee = new Employee(null, role);

        ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
        String json = ow.writeValueAsString(expectedEmployee);

        ResultActions resultActions = this.mockMvc.perform(post(PATH)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(json))
                .andDo(print());

        String contentAsString = resultActions.andReturn().getResponse().getContentAsString();
        System.out.println("content: " + contentAsString); // empty body

        resultActions
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("error").exists())      // not exist!!!
                .andExpect(jsonPath("timestamp").exists()); // not exist!!!

    }
}

employee.xml:

<dataset>
    <Employee id="1" name="John" role="admin"/>
    <Employee id="2" name="Mike" role="user"/>
</dataset>

I can not understand why it does not work when I test through @MockMvc. What am i doing wrong? Status is correct, but there is no error content, empty response

But validation works if tested on a really running application, then everything works.

来源:https://stackoverflow.com/questions/55088583/mockmvc-does-not-work-with-validation-annotated-with-valid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!