您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如何干净地测试使用DomainClassConverter检索参数的Spring控制器?

如何干净地测试使用DomainClassConverter检索参数的Spring控制器?

因此,从DomainClassConverter小型文档中,我知道它使用CrudRepository#findById查找实体。我想知道的是如何在测试中清晰地进行模拟。

您将需要模拟2个在之前调用方法CrudRepository#findById以便返回所需的实体。下面的示例使用RestAssuredmockmvc,但是如果同时注入mockmvc,则可以执行相同的操作WebApplicationContext

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SomeApplication.class)
public class SomeControllerTest {

    @Autowired
    private WebApplicationContext context;

    @MockBean(name = "mvcConversionService")
    private WebConversionService webConversionService;

    @Before
    public void setup() {
        RestAssuredmockmvc.webAppContextSetup(context);

        SomeEntity someEntity = new SomeEntity();

        when(webConversionService.canConvert(any(TypeDescriptor.class), any(TypeDescriptor.class)))
                .thenReturn(true);

        when(webConversionService.convert(eq("1"), any(TypeDescriptor.class), any(TypeDescriptor.class)))
                .thenReturn(someEntity);
    }
}

在某个时候,Spring Boot将执行WebConversionService::convert,稍后将调用DomainClassConverter::convert,然后执行类似的操作invoker.invokeFindById,该操作将使用实体存储库查找实体。

那么为什么要嘲笑WebConversionService而不是DomainClassConverter呢?因为DomainClassConverter是在应用程序启动期间实例化的,没有注入:

DomainClassConverter<FormattingConversionService> converter =
        new DomainClassConverter<>(conversionService);

同时,WebConversionService一个可以让我们模拟它的bean:

@Bean
@Override
public FormattingConversionService mvcConversionService() {
    WebConversionService conversionService = new WebConversionService(this.mvcProperties.getDateFormat());
    addFormatters(conversionService);
    return conversionService;
}

将模拟bean命名为mvcConversionService,这一点很重要,否则它将不会替换原始bean。

关于存根,您将需要模拟2个方法。首先,您必须告诉您的模拟可以转换任何内容

when(webConversionService.canConvert(any(TypeDescriptor.class), any(TypeDescriptor.class)))
        .thenReturn(true);

然后是main方法,它将与URL路径中定义的所需实体ID相匹配:

when(webConversionService.convert(eq("1"), any(TypeDescriptor.class), any(TypeDescriptor.class)))
        .thenReturn(someEntity);

到目前为止,一切都很好。但是匹配目标类型也不会更好吗?像eq(TypeDescriptor.valueOf(SomeEntity.class))什么?可以,但是这会创建TypeDescriptor的新实例,当在域转换期间调用此存根时,它将不匹配。

这是我使用过的最干净的解决方案,但是我知道,如果Spring允许,它可能会更好。

Java 2022/1/1 18:32:41 有386人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶