Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用具有独立上下文和SpringBoot 1.2.5的MockMvcBuilders进行文件上载的单元测试_Java_Spring_Unit Testing_Spring Mvc_Multipartform Data - Fatal编程技术网

Java 使用具有独立上下文和SpringBoot 1.2.5的MockMvcBuilders进行文件上载的单元测试

Java 使用具有独立上下文和SpringBoot 1.2.5的MockMvcBuilders进行文件上载的单元测试,java,spring,unit-testing,spring-mvc,multipartform-data,Java,Spring,Unit Testing,Spring Mvc,Multipartform Data,我使用的是Spring Boot 1.2.5版本。我有一个控制器,它接收一个多部分文件和一个字符串 @RestController @RequestMapping("file-upload") public class MyRESTController { @Autowired private AService aService; @RequestMapping(method = RequestMethod.POST, consumes = MediaType.MULTIPART

我使用的是Spring Boot 1.2.5版本。我有一个控制器,它接收一个
多部分文件
和一个
字符串

@RestController
@RequestMapping("file-upload")
public class MyRESTController {

  @Autowired
  private AService aService;

  @RequestMapping(method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  @ResponseStatus(HttpStatus.CREATED)
  public void fileUpload(
      @RequestParam(value = "file", required = true) final MultipartFile file,
      @RequestParam(value = "something", required = true) final String something) {
   aService.doSomethingOnDBWith(file, value);
  }
}
现在,服务很好。我和邮递员一起测试过,一切都如期进行。 不幸的是,我无法为该代码编写独立的单元测试。当前的单元测试是:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
public class ControllerTest{

    MockMvc mockMvc;

    @Mock
    AService aService;

    @InjectMocks
    MyRESTController controller;

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

  @Test
  public void testFileUpload() throws Exception{
        final File file = getFileFromResource(fileName);
        //File is correctly loaded
        final MockMultipartFile multipartFile = new MockMultipartFile("aMultiPartFile.txt", new FileInputStream(file));

        doNothing().when(aService).doSomethingOnDBWith(any(MultipartFile.class), any(String.class));

        mockMvc.perform(
                post("/file-upload")
                        .requestAttr("file", multipartFile.getBytes())
                        .requestAttr("something", ":(")
                        .contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
                .andExpect(status().isCreated());
    }
}
测试失败,原因是

java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
现在,在Spring Boot的
MultipartAutoConfiguration
类中,我看到一个
MultipartResolver
是自动配置的。但是,我想通过
MockMvcBuilders
standaloneSetup
,我无法访问它

我尝试了几个单元测试的配置,为了简洁起见,我没有报告这些配置。特别是,我还尝试了如图所示的rest-assured,但老实说,这不起作用,因为我似乎无法模拟
AService
实例


有什么解决方案吗?

您试图在这里将单元测试(
standaloneSetup(controller.build();
)与Spring集成测试(
@RunWith(SpringJUnit4ClassRunner.class)
)结合起来

做一个或另一个

  • 集成测试需要使用下面的代码。问题是伪造豆子。有很多方法可以用
    @Primary
    注释和
    @Profile
    注释来伪造这样的bean(您创建的测试bean将覆盖主生产bean)。我有一些假冒春豆的例子(例如,被in替换)

  • Secodn选项是删除测试和测试控制器上的
    @RunWith(SpringJUnit4ClassRunner.class)
    和其他类级配置,而不使用独立设置的Spring上下文。这样,您就不能在控制器上测试验证注释,但可以使用SpringMVC注释。优点是可以通过Mockito(例如通过injectmock和Mock注释)伪造bean


  • 错误表示请求不是由多个部分组成的请求。换句话说,在这一点上,它应该已经被解析了。然而,在MockMvc测试中没有实际的请求。这只是模拟请求和响应。因此,您需要使用perform.fileUpload(…)来设置模拟文件上传请求。

    我混合了建议和Mockito
    @Spy
    功能。我用“放心”来打电话。因此,我做了如下工作:

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = MyApplication.class)
    @WebAppConfiguration
    @IntegrationTest({"server.port:0"})
    public class ControllerTest{
    
        {
          System.setProperty("spring.profiles.active", "unit-test");
        }
    
    
        @Autowired
        @Spy
        AService aService;
    
        @Autowired
        @InjectMocks
        MyRESTController controller;
    
        @Value("${local.server.port}")
        int port;    
    
    
      @Before public void setUp(){
        RestAssured.port = port;
    
        MockitoAnnotations.initMocks(this);
      }
    
      @Test
      public void testFileUpload() throws Exception{
            final File file = getFileFromResource(fileName);
    
            doNothing().when(aService)  
                 .doSomethingOnDBWith(any(MultipartFile.class), any(String.class));
    
            given()
              .multiPart("file", file)
              .multiPart("something", ":(")
              .when().post("/file-upload")
              .then().(HttpStatus.CREATED.value());
        }
    }
    
    该服务定义为

    @Profile("unit-test")
    @Primary
    @Service
    public class MockAService implements AService {
      //empty methods implementation
    }
    

    第二个选项不起作用:我删除了测试类的所有注释,从您提到的注释开始,但结果是:
    org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常为java.lang.IllegalArgumentException:预期的MultipartTTpServletRequest:是否配置了MultipartResolver?
    。现在我尝试第一种方法。第一种方法有一些缺点。假设我使用了几个服务,并且我想测试几个行为。然后,我必须在为集成测试概要文件定义的服务中定义不同行为的选项。您原来的方法根本不起作用。没有机会。我只是列举了两种方法,即如何进行MockMvc测试。你必须用一个或另一个来解决这个问题。你能写一个完整的例子吗?这里举个例子
    @Profile("unit-test")
    @Primary
    @Service
    public class MockAService implements AService {
      //empty methods implementation
    }