【问题标题】:Creating a MultipartFormDataInput object for Java jUnit testing为 Java jUnit 测试创建 MultipartFormDataInput 对象
【发布时间】:2026-02-09 16:35:01
【问题描述】:

我有一个 Resteasy webservice 方法,它以 MultipartFormDataInput 对象作为参数,并从中提取大量信息。我想为此方法编写一个 jUnit 测试,但我一直无法找到任何方法来创建此对象并将虚拟数据放入其中,因此我可以直接调用我的 webservice 方法。服务方法像这样从表单中提取数据...

@POST
@Path("/requestDeviceCode")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Consumes("multipart/form-data")
public DeviceCodeModel requestDeviceCode(final MultipartFormDataInput inputMultipart) {

    // process the form data - only field in the form is the token
    Map<String, List<InputPart>> formData = null; // we'll put the form data in here
    formData = inputMultipart.getFormDataMap();

    String token = null;
    try {
        token = formData.get("Token").get(0).getBodyAsString();
        this._logger.debug("Pulled encrypted token out of input form, it's " + token);

这很好用,但试图创建一个对象作为参数传递给“requestDeviceCode”让我受阻。我已经尝试过这种变体...

        // create a multipartForm (input to the service POST) and add the "token" string to it
        MultipartFormDataOutput newForm = new MultipartFormDataOutput();
        newForm.addFormData("Token", encryptedXMLString, MediaType.APPLICATION_XML_TYPE);

        _service.requestDeviceCode((MultipartFormDataInput) newForm);

但它只是没有这样做(这个特定的错误是我无法将输出表单转换为输入表单)。我一直无法找到一种方法来创建新的 MultiPartFormDataInput 并向其添加数据。

有人有什么建议吗?

【问题讨论】:

  • 您是在尝试测试代码从 MultiPartFormDataInput 中提取数据的能力,还是测试您的程序是否正确使用了从对象中获取的数据?
  • 为此,我正在测试我的代码从表单中正确提取数据的能力。我有其他测试调用使用从表单中提取的令牌的方法,并且这些测试正在工作,但为了完整起见,我希望有一个集成测试来测试这个服务端到端,因此试图创建并填充 MultipartFormDataInput 对象。
  • 想知道您是否对此有进一步了解...

标签: java junit resteasy multipartform-data


【解决方案1】:

在尝试对我的 RestEasy WebService 的接受 MultipartFormDataInput 的方法进行单元测试时,我偶然发现了一个类似的问题。

您可以做的是模拟 MultipartFormDataInput 以返回一个准备好的地图,其中包含您希望收到的每个表单参数的模拟 InputPart

可能的解决方案(使用 JUnit/Mockito):

@Test
public void testService() {
    // given
    MultipartFormDataInput newForm = mock(MultipartFormDataInput.class);
    InputPart token = mock(InputPart.class);

    Map<String, List<InputPart>> paramsMap = new HashMap<>();
    paramsMap.put("Token", Arrays.asList(token));        

    when(newForm.getFormDataMap()).thenReturn(paramsMap);
    when(token.getBodyAsString()).thenReturn("expected token param body");
    // when
    DeviceCodeModel actual = _service.requestDeviceCode(newForm);
    // then
    // verifications and assertions go here
}

【讨论】:

    【解决方案2】:

    做一个集成测试怎么样?
    启动测试中嵌入的 jetty 或 Tomcat 并让它运行您的 REST 服务。 作为 HTTP 客户端,我将使用 Apache HttpComponents 客户端,请参阅 Tutorialexamples page 上的 MultiPart 客户端示例。

    【讨论】:

    • 这是一种可能性,但我希望找到可以像其他测试一样即时执行的东西,而不是每次都需要启动服务器的东西。
    • 您仍然可以通过使用 maven failsafe plugin 以及在您的集成测试阶段自动启动和关闭 Jetty 来自动执行此操作并将其集成到您的持续集成中,请参阅 Automatic execution of the插件在maven Jetty Plugin documentation.