【问题标题】:Unit testing field validation with MockMvc but without Spring context?使用 MockMvc 但没有 Spring 上下文的单元测试字段验证?
【发布时间】:2016-07-31 08:02:54
【问题描述】:

是否可以使用MockMvcMockitoJUnitRunner 测试@Valid 注释?我可以测试我的 CRUD 控制器的大部分行为,但验证似乎需要使用 Spring 的 JUnit 运行器,构建整个上下文并创建需要很多东西的 JPA 存储库实现。

下面的测试尝试测试接收Customer 实体的POST 方法,其中firstName 字段使用@Size(min=2, max=20) 进行注释。结果是

java.lang.AssertionError: View name expected:<edit> but was:<redirect:/info>

所以验证没有运行。

@RunWith(MockitoJUnitRunner.class)
public class DataControllerTest {
    @Mock
    CustomerRepository mockRepo;

    @InjectMocks
    private DataController controller;

    MockMvc mockmvc;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
        mockmvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @Test
    public void testBadSubmit() throws Exception {
        mockmvc.perform(MockMvcRequestBuilders.post("/edit/1")
            .param("firstName", "a"))
            .andExpect(MockMvcResultMatchers.view().name("edit"));
        Mockito.verifyZeroInteractions(mockRepo);
    }
} 

控制器类:

@Controller
public class DataController {
    @Autowired
    public CustomerRepository crep;

    ...

    @RequestMapping(value = {"/edit/{id}"}, method = RequestMethod.POST)
    public String add(Model model, @Valid Customer customer, Errors result) {
        if (result.hasErrors()) {
            return "edit";
        }
        crep.save(customer);
        return "redirect:/info";
    }

实体:

@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id = null;

    @Column(length=20)
    @Size(min=2, max=20)
    private String firstName;
    ...
}

JPA 存储库接口:

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {

    List<Customer> findByLastName(String lastName);
}

【问题讨论】:

    标签: validation unit-testing spring-mvc mockito spring-data-jpa


    【解决方案1】:

    SpringJUnit4ClassRunner 的目的是自动加载应用程序上下文并自动连接所有内容。您应该能够使用MockitoJUnitRunner,但您必须加载要在测试中手动使用的应用程序上下文。但是无论如何,您确实需要加载应用程序上下文,因为通过 Spring 调用 DataController#add() 是处理 @Valid 注释的唯一方法。

    编辑:如果这里真正的问题是加载 JPA 存储库,您可以使用 MockitoJUnitRunner 并只需加载一个手动连接模拟 JPA 存储库的测试应用程序上下文,几乎没有费用。

    【讨论】:

    • 我不确定如何创建一个应用程序上下文来处理@Valid 注释但不会抱怨缺少 JPA 存储库 bean,除非我设置了 @Autowired(required=false)
    • 只要封闭类连接到测试类或由测试类从应用程序上下文中检索到,@Valid 注释就会被测试。如果您需要一些示例代码,请告诉我。
    • 如果问题不大,请举个例子。
    猜你喜欢
    • 1970-01-01
    • 2017-07-14
    • 2013-12-28
    • 2015-11-20
    • 1970-01-01
    • 2018-06-26
    • 2017-03-07
    • 1970-01-01
    • 2015-03-29
    相关资源
    最近更新 更多