当前位置: 首页 > 面试题库 >

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

充浩波
2023-03-14
问题内容

我擅长进行干净,隔离良好的单元测试。但是我在这里的“干净”部分碰巧测试一个控制器,该控制器使用DomainClassConverter功能获取实体作为其映射方法的参数。

@Entity
class MyEntity {
    @Id
    private Integer id;
    // rest of properties goes here.
}

像这样定义控制器

@RequestMapping("/api/v1/myentities")
class MyEntitiesController {
    @Autowired
    private DoSomethingService aService;

    @PostMapping("/{id}")
    public ResponseEntity<MyEntity> update(@PathVariable("id")Optional<MyEntity> myEntity) {
        // do what is needed here
    }
}

因此,从DomainClassConverter小型文档中,我知道它用于CrudRepository#findById查找实体。我想知道的是如何在测试中清晰地进行模拟。通过执行以下步骤,我取得了一些成功:

  1. 创建一个我可以模拟的自定义转换器/格式化程序
  2. 使用上述转换器实例化我自己的MockMvc
  3. 重置模拟并在每次测试时更改行为。

问题在于设置代码很复杂,因此难以调试和解释(我的团队是来自Rails或uni的99%的初级人员,因此我们必须保持简单)。我想知道是否有一种方法可以MyEntity在继续使用进行测试的同时从单元测试中注入所需的实例@Autowired
MockMvc

目前,我正在尝试查看是否可以插入CrudRepositoryfor 的模拟物,MyEntity但没有成功。几年来我一直没有在Spring /
Java中工作(4),所以我对可用工具的了解可能不是最新的。


问题答案:

因此,从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允许,它可能会更好。



 类似资料:
  • 我将这个方法设置为从Spring Boot rest控制器返回一个响应: 这是DAO方法: 我成功地拥有一个json对象作为响应,但格式如下: 当我期待有: 为什么将结果集插入到< code>#result-set-1键中?我如何改变这种行为?

  • 我正在开发一个使用Spring Boot的项目。我有一个接受GET请求的控制器。 目前,我正在接受对以下类型URL的请求:

  • 我有下一个Rest控制器 我将Spring Security用于以下配置: 我想为我的控制器编写单元测试。我写了下一个测试,但是它们工作得不好: 当我开始测试时,我得到了状态404。如果在安全配置中删除@EnableGlobalmetodSecurity(prePostEnable=true),测试正在工作,但不工作@PreAuthorize。我有一些问题: 如果prespenabled=true

  • 问题内容: 我正在使用spring 3.2.0和junit 4 这是我需要测试的控制器方法 spring-servlet config is: This is my test class : 如何使用MockMvc测试此方法? 问题答案: 你可以使用以下注释来使用应用程序调度程序servlet xml。以下示例使用路径/ mysessiontest设置了一些会话属性并期望返回某个视图来命中控制器:

  • 问题内容: 这是我的.htaac​​cess代码。 我需要网站的干净URL。我参考了许多教程和论坛,并创建了上面的代码。但是无法正常工作。几乎我正在与代码作斗争。我不太清楚干净的URL概念。我要在我的php页面上编写任何编码吗? 我在index.php文件中有此链接。 我想要同时点击链接泰坦尼克号。 我也想通过$ _ [request]获得值。 我到底要做什么。请不要重复提出这个问题,我已经搜索了

  • 我有一个请求表单的映射: 现在我想用MockMvcBuilders为此编写一个测试。不过,我不能这样做。 这里的挑战是请求处理程序需要使用Multipart/form-data,它由4个Multipart Files和1个Json数据组成。 有没有办法解决这个问题?请记住,我必须使用Spring 4.3。 如果您需要更多信息,请告诉我。