@MockMvc 不适用于使用 @Valid 注释的验证

问题描述 投票:0回答:1

这些解决方案都没有帮助:Spring mockMvc 在我的测试中不考虑验证。添加了所有这些依赖项,没有任何帮助。

我使用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>

我使用标准休眠验证'@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> {

}

然后我测试我的控制器:

@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>

我不明白为什么当我通过@MockMvc测试时它不起作用。我究竟做错了什么?状态正确,但没有错误内容,空响应

但是如果在真正运行的应用程序上进行测试,验证就有效,那么一切都有效。

java spring-boot hibernate-validator spring-boot-test spring-mvc-test
1个回答
0
投票

我可以使用 Spring-boot 3.3.1 重现这个问题
与 MockMvc +

@AutoConfigureMockMvc

或使用 WebTestClient +
@AutoConfigureWebTestClient

通过从 JUNIT 类测试(以及所有测试方法)中删除注释 @Transactional

 
解决了

因此,数据库约束和验证异常通常由 Hibernate 的 JPA 层抛出。

© www.soinside.com 2019 - 2024. All rights reserved.