单元测试Spring Boot MultiPartFile PDF使用MockMvc上传Rest控制器

时间:2016-06-10 07:38:11

标签: rest spring-mvc spring-boot mockito junit4

好日子好朋友, 我是Springboot的新手,在测试我的PDF上传器弹簧控制器端点时遇到了问题。 其余端点在通过邮递员测试时起作用,但在我的单元测试中不起作用。 我正在使用具有以下关键组件的spring boot应用程序,问题是:

org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
    at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:251)

2016-06-09 19:03:03,359 4198 [main] DEBUG o.s.t.c.w.ServletTestExecutionListener - Resetting RequestContextHolder for test context [DefaultTestContext@646be2c3 testClass = PDFUploadControllerTest, testInstance = x.y.z.rest.controller.PDFUploadControllerTest@2b44d6d0, testMethod = testHandleFileUpload@PDFUploadControllerTest, testException = java.lang.AssertionError: Status expected:<200> but was:<400>, mergedContextConfiguration = [WebMergedContextConfiguration@797badd3 testClass = PDFUploadControllerTest, locations = '{}', classes = '{class x.y.z.rest.PresentationConfiguration, class x.y.z.rest.controller.MockDomainConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]].

java.lang.AssertionError: Status 
Expected :200
Actual   :400

请看下面的一些代码和堆栈跟踪...我一直在墙上敲打我的头,使用所有在线参考调试,但没有运气.... 非常感谢您的帮助。感谢

应用
@EnableAutoConfiguration()
public class Application {

    public static void main(String[] args) {
SpringApplication.run(
                new Object[]{
                        DomainConfiguration.class,
                        PresentationConfiguration.class
},
                args);
    }
}
DomainConfiguration
@Configuration
@EnableAutoConfiguration()
@ComponentScan(basePackages = {
        "x.y.z.rest.domain",
        "x.y.z.rest.service",
        "x.y.z.rest.util",
        "x.y.z.rest.repository"
})
public class DomainConfiguration {
    @Autowired(required = true)
    public void configeJackson(ObjectMapper jackson2ObjectMapper) {
        jackson2ObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }

}
PresentationConfiguration
@Configuration
@ComponentScan(basePackages = {"x.y.z.rest.controller"})
public class PresentationConfiguration {
}
## RestController
    @RestController
    public class PDFUploadController {

       @Autowired
        public void setUploadService(UploadService uploadService) {
            this.uploadService = uploadService;
        }

        private UploadService uploadService;

        @RequestMapping(value="/upload", method=RequestMethod.POST)
        @ResponseStatus(HttpStatus.CREATED)
        public @ResponseBody String handleFileUpload(
                @RequestParam("file") MultipartFile file,@RequestParam String a,@RequestParam String b,@RequestParam String c, @RequestParam String d,@RequestParam String e) throws Exception{
            java.io.InputStream inputStream =null;


            if (!file.isEmpty() && checkContentType(file.getContentType())) {
                try {
                     DBObject dbObject = new BasicDBObject();
                     //populate DBObject                     
                    inputStream = file.getInputStream();
uploadService.uploadFile(inputStream,file.getOriginalFilename(),file.getContentType(),dbObject);

                    return "success";
                } catch (Exception e) {
                    return "You failed to upload " + file.getOriginalFilename() + " => " + e.getMessage();
                }
                finally {
                    if(inputStream!=null) {
                        inputStream.close();
                    }


                }
            } else {
                return "You failed to upload " + file.getOriginalFilename() + " as it is an invalid file.";
            }
        }
    }
#####控制器的单元测试类
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {
        PresentationConfiguration.class,
        MockDomainConfiguration.class})
@WebAppConfiguration

public class PDFUploadControllerTest {

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    private UploadService uploadService;
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper mapper;
    private RestDocumentationResultHandler document;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                .build();
    }

    @After
    public void resetMocks() {

        reset(uploadService);
    }


    @Test
    public void testHandleFileUpload() throws Exception {
        FileInputStream fileInputStream = null;
        MockMultipartFile mockMultipartFile = null;

        try {
            File file = new File("//Users//olatom//Desktop//testFile4Upload.pdf");

            // create FileInputStream object
            fileInputStream = new FileInputStream(file);
            System.out.println("# File input stream for PDF : " + fileInputStream);

            byte fileContent[] = new byte[(int) file.length()];

            // Reads up to certain bytes of data from this input stream into an array of bytes.
            fileInputStream.read(fileContent);
            //create string from byte array
            String pdfContent = new String(fileContent);

            //mockMultipartFile = new MockMultipartFile("upload", file.getName(), "multipart/form-data", fileInputStream);

            mockMultipartFile = new MockMultipartFile("file", fileInputStream);

            HashMap<String, String> contentTypeParams = new HashMap<String, String>();
            contentTypeParams.put("boundary", "265001916915724");
            MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);

            //mockMvc.perform(fileUpload("/upload")
            //        .file(mockMultipartFile)
            //        .param("a", "1234").param("b", "PX1234").param("c", "100").param("d", "120")
            //       .contentType(MediaType.MULTIPART_FORM_DATA))
            //      .andExpect(status().isOk());

            // mockMvc.perform(fileUpload("/upload")).andExpect(status().isOk());
            //mockMvc.perform(fileUpload("/upload").file(mockMultipartFile)).andExpect(status().isOk());

            mockMvc.perform(
                    fileUpload("/upload")
                            .content(mockMultipartFile.getBytes())
                            .param("a", "1234").param("b", "PX1234").param("c", "100").param("d", "120")
                            .contentType(mediaType)
            )
                    .andExpect(status().isOk());
        } catch (FileNotFoundException e) {
            System.out.println("File not found" + e);
        } catch (IOException ioe) {
            System.out.println("IO Exception while reading file " + ioe);
        } catch (Exception exc) {
        } finally {
            // close the streams using close method
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (IOException ioe) {
                System.out.println("Error while closing stream: " + ioe);
            }
        }
    }
}

####### MockDomainConfiguration #####

/**
 * Create Mockito mocks for the service classes.
 * For this to work the @EnableAutoConfiguration annotation below also has to exclude JPA Autoconfiguration.
 */
@Configuration
@EnableAutoConfiguration()
public class MockDomainConfiguration { 

    @Bean
    public UploadService mockUploadService() {
        return mock(UploadService.class);
    } 
}
##我的错误

当我在Intellij中运行junit测试时,我收到以下错误:

2016-06-09 19:03:03,331 4170 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - DispatcherServlet with name '' processing POST request for [/upload]
2016-06-09 19:03:03,342 4181 [main] DEBUG o.s.b.a.e.m.EndpointHandlerMapping - Looking up handler method for path /upload
2016-06-09 19:03:03,343 4182 [main] DEBUG o.s.b.a.e.m.EndpointHandlerMapping - Did not find handler method for [/upload]
2016-06-09 19:03:03,343 4182 [main] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /upload
2016-06-09 19:03:03,344 4183 [main] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]
2016-06-09 19:03:03,344 4183 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'PDFUploadController'
2016-06-09 19:03:03,352 4191 [main] DEBUG o.s.w.s.m.m.a.ServletInvocableHandlerMethod - Error resolving argument [0] [type=org.springframework.web.multipart.MultipartFile]
HandlerMethod details: 
Controller [x.y.z.rest.controller.PDFUploadController]
Method [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]

org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
    at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:251)
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:96)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
    at x.y.z.rest.controller.PDFUploadControllerTest.testHandleFileUpload(PDFUploadControllerTest.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
2016-06-09 19:03:03,353 4192 [main] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]: org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
2016-06-09 19:03:03,354 4193 [main] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]: org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
2016-06-09 19:03:03,354 4193 [main] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]: org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
2016-06-09 19:03:03,355 4194 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Null ModelAndView returned to DispatcherServlet with name '': assuming HandlerAdapter completed request handling
2016-06-09 19:03:03,355 4194 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Successfully completed request
2016-06-09 19:03:03,359 4198 [main] DEBUG o.s.t.c.s.AbstractDirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@646be2c3 testClass = PDFUploadControllerTest, testInstance = x.y.z.rest.controller.PDFUploadControllerTest@2b44d6d0, testMethod = testHandleFileUpload@PDFUploadControllerTest, testException = java.lang.AssertionError: Status expected:<200> but was:<400>, mergedContextConfiguration = [WebMergedContextConfiguration@797badd3 testClass = PDFUploadControllerTest, locations = '{}', classes = '{class x.y.z.rest.PresentationConfiguration, class x.y.z.rest.controller.MockDomainConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]], class annotated with @DirtiesContext [false] with mode [null], method annotated with @DirtiesContext [false] with mode [null].
2016-06-09 19:03:03,359 4198 [main] DEBUG o.s.t.c.w.ServletTestExecutionListener - Resetting RequestContextHolder for test context [DefaultTestContext@646be2c3 testClass = PDFUploadControllerTest, testInstance = x.y.z.rest.controller.PDFUploadControllerTest@2b44d6d0, testMethod = testHandleFileUpload@PDFUploadControllerTest, testException = java.lang.AssertionError: Status expected:<200> but was:<400>, mergedContextConfiguration = [WebMergedContextConfiguration@797badd3 testClass = PDFUploadControllerTest, locations = '{}', classes = '{class x.y.z.rest.PresentationConfiguration, class x.y.z.rest.controller.MockDomainConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]].

java.lang.AssertionError: Status 
Expected :200
Actual   :400
 <Click to see difference>


    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
    at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:655)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
    at x.y.z.rest.controller.PDFloadControllerTest.testHandleFileUpload(PDFUploadControllerTest.java:146)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

非常感谢您的帮助。

0 个答案:

没有答案