当前位置: 首页 > 知识库问答 >
问题:

Spring MockMVC-如何模拟在控制器之外运行的自定义验证程序

逑衡
2023-03-14
@UsernameAlreadyExists
private String username;

我创建了一个自定义验证器,以确保在提交帐户创建表单时,应用程序会捕获重复的用户名。

当我使用MockMVC对帐户创建控制器进行单元测试时,它失败了,因为验证器依赖于服务,所以我得到了空指针异常。

我怎么能嘲笑验证器或验证器所依赖的服务呢?我不知道如何让它工作,因为控制器不明确依赖于验证器,它在控制器之外运行。

共有2个答案

师曦
2023-03-14

您不能嘲笑ConstraintValidator,但您当然可以嘲笑验证器所依赖的服务,使用通常的Spring方式嘲笑bean,例如:

.1.可能会使用完全相同的bean名称定义一个mock实例,以确保在实际实例之后加载您的带有mock的配置。

.2.只使用定义了模拟bean的测试配置进行测试。

周承天
2023-03-14

在使用“StandaloneStup”进行测试时,在不加载整个Spring上下文的情况下,通过SpringWebConstraintValidatorFactory上的框架调用在内部触发验证。为了连接到该流,您需要在“mockMvc”中设置SpringWebConstraintValidatorFactory的新实例<不幸的是,没有一种简单干净的方法可以做到这一点。您必须子类化SpringWebConstraintValidatorFactory,并在LocalValidatoryBean中设置实例,然后可以在mockMvc中设置实例。但是LocalValidatoryFactoryBean需要ApplicationContext。下面是一个例子:



    public class TestConstrainValidationFactory extends SpringWebConstraintValidatorFactory {

        private final WebApplicationContext ctx;

        private boolean isValid = false;

        public TestConstrainValidationFactory(WebApplicationContext ctx) {
            this.ctx = ctx;
        }

        @Override
        public < T extends ConstraintValidator<?, ?>> T getInstance(Class key) {
            ConstraintValidator instance = super.getInstance(key);
            if (instance instanceof DeviceValidator) {
                DeviceValidator deviceValidator = (DeviceValidator) instance;
                deviceValidator.setYourAutowiredField((String id, String type) -> isValid); //change that to suit your needs
                instance = deviceValidator;
            }
            return (T) instance;
        }

        @Override
        protected WebApplicationContext getWebApplicationContext() {
            return ctx;
        }

    }

将其连接到mockMvc的示例



    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = MockServletContext.class)
    @WebAppConfiguration()
    public class DevicesControllerTest {
        @Autowired
        private MockServletContext servletContext;
        @InjectMocks
        private DevicesController devicesController;
        private TestConstrainValidationFactory constraintFactory;

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

            final GenericWebApplicationContext context = new GenericWebApplicationContext(servletContext);
            final ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) context).getBeanFactory();
            beanFactory.registerSingleton(DeviceValidator.class.getCanonicalName(), new DeviceValidator());
            context.refresh();

            LocalValidatorFactoryBean validatorFactoryBean = new LocalValidatorFactoryBean();
            validatorFactoryBean.setApplicationContext(context);
            constraintFactory = new TestConstrainValidationFactory(context);
            validatorFactoryBean.setConstraintValidatorFactory(constraintFactory);
            validatorFactoryBean.setProviderClass(HibernateValidator.class);
            validatorFactoryBean.afterPropertiesSet();

            this.mockMvc = MockMvcBuilders
                    .standaloneSetup(devicesController)
                    .setValidator(validatorFactoryBean)
                    .setHandlerExceptionResolvers()
                    .build();
        }
    }

一旦你有了它,ReflateTestUtils.set字段(约束工厂,"isValid",false);将按预期工作,你可以通过工厂在验证器中设置字段。

 类似资料:
  • 我知道有一个有效的注释,它指示spring根据JSR-303验证一个控制器参数,在这个示例中: 但我希望能够以某种方式配置Spring,以便在所有控制器中启用验证,而无需明确指定有效的注释。 这有可能吗?一些Spring配置?利用AOP?。。。

  • 请让我知道,如果这是不是正确的地方发布,但我一直在寻找有关这方面的信息,似乎找不到一个简洁的答案。 我一直在尝试使用KeyClope来满足我们应用程序的用户管理需求。虽然我发现KeyClope非常有能力,也非常有效,但我已经进入了我们使用的死胡同。 背景: 传统上,我们的应用程序使用一个非常基本的登录框架来验证身份验证。然后使用我们无法更改的第三方应用程序,确定用户将通过wsdl操作拥有的角色,并

  • 问题内容: 我有其他人编写的REST api,其中处理请求到特定url的方法接受一堆从路径参数填充的参数。 撰写此文章的人曾经使用过DropWizard,但我以前没有使用它的经验。我的任务是通过将其与db中的值进行比较来验证studentId字段。这将非常简单,但是我被告知要使用自定义验证程序来执行此操作。我对编写注释非常陌生,但经过大量挖掘后,这样编写了注释, 此后,我将注释添加到了要像这样运行

  • 我正在构建一个Spring Boot应用程序,并试图为我将在服务层验证的一些DTO/实体实现自定义验证。基于Spring关于这个问题的文档,我认为一种方法是实现org。springframework。验证。验证程序界面。 作为一个最小、完整、可重复的示例,请考虑以下代码: Spring初始化引导项目 在src/main/java/com中添加了以下代码。实例使用验证: 如果我点击endpoint触

  • 我有以下验证器,用于验证更新请求。 object.getIdCreditor()有一个值,但是findById方法的执行["CreditorRepository.findById(object.getIdCreditor())" ] 进入NullPointer异常 我不明白怎么了。

  • 总结 如何在Django MongoEngine中使用自定义用户模型和自定义身份验证后端(允许电子邮件/密码身份验证)?(这是否需要自定义后端?…即,在使用MongoEngine进行身份验证时使用电子邮件作为用户名。) 是否有直接(完整)的文档在Django中进行身份验证时,将Mongo用作主数据存储时使用自定义用户对象的示例?(博士后有如此清晰和全面的文档…) 细节 MongoEngine似乎只