স্প্রিং এমভিসি টেস্ট থেকে ইউনিট পরীক্ষার মাল্টিপার্ট POST অনুরোধ ব্যবহার করে


115

অটো সংরক্ষণের জন্য আমার কাছে নিম্নলিখিত অনুরোধ হ্যান্ডলারটি রয়েছে। আমি যাচাই করেছি যে আমি যখন সিআরএল ব্যবহার করি তখন এটি কাজ করে। এখন আমি স্প্রিং এমভিসি টেস্টের সাথে পদ্ধতিটি ইউনিট করতে চাই। আমি ফাইল আপলোডারটি ব্যবহার করার চেষ্টা করেছি, তবে এটি কাজ করার জন্য আমি পরিচালনা করছি না। আমি জেএসএন অংশ যোগ করার ব্যবস্থা করি না।

আমি স্প্রিং এমভিসি পরীক্ষার সাথে এই পদ্ধতিটি কীভাবে পরীক্ষা করব? আমি এটির কোনও উদাহরণ খুঁজে পাচ্ছি না।

@RequestMapping(value = "autos", method = RequestMethod.POST)
public ResponseEntity saveAuto(
    @RequestPart(value = "data") autoResource,
    @RequestParam(value = "files[]", required = false) List<MultipartFile> files) {
    // ...
}

আমি আমার অটো + এক বা একাধিক ফাইলের জন্য একটি JSON উপস্থাপনা আপডল করতে চাই।

আমি সঠিক উত্তরে 100 টি অনুগ্রহ যুক্ত করব!

উত্তর:


256

যেহেতু MockMvcRequestBuilders#fileUploadনিন্দা করা হয়েছে, আপনি ব্যবহার করতে চাইবেন MockMvcRequestBuilders#multipart(String, Object...)যা ফেরৎ MockMultipartHttpServletRequestBuilder। তারপরে একগুচ্ছ file(MockMultipartFile)কল।

এখানে একটি কাজের উদাহরণ। দেওয়া a@Controller

@Controller
public class NewController {

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public String saveAuto(
            @RequestPart(value = "json") JsonPojo pojo,
            @RequestParam(value = "some-random") String random,
            @RequestParam(value = "data", required = false) List<MultipartFile> files) {
        System.out.println(random);
        System.out.println(pojo.getJson());
        for (MultipartFile file : files) {
            System.out.println(file.getOriginalFilename());
        }
        return "success";
    }

    static class JsonPojo {
        private String json;

        public String getJson() {
            return json;
        }

        public void setJson(String json) {
            this.json = json;
        }

    }
}

এবং একটি ইউনিট পরীক্ষা

@WebAppConfiguration
@ContextConfiguration(classes = WebConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class Example {

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Test
    public void test() throws Exception {

        MockMultipartFile firstFile = new MockMultipartFile("data", "filename.txt", "text/plain", "some xml".getBytes());
        MockMultipartFile secondFile = new MockMultipartFile("data", "other-file-name.data", "text/plain", "some other type".getBytes());
        MockMultipartFile jsonFile = new MockMultipartFile("json", "", "application/json", "{\"json\": \"someValue\"}".getBytes());

        MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        mockMvc.perform(MockMvcRequestBuilders.multipart("/upload")
                        .file(firstFile)
                        .file(secondFile)
                        .file(jsonFile)
                        .param("some-random", "4"))
                    .andExpect(status().is(200))
                    .andExpect(content().string("success"));
    }
}

এবং @Configurationক্লাস

@Configuration
@ComponentScan({ "test.controllers" })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurationSupport {
    @Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        return multipartResolver;
    }
}

পরীক্ষাটি পাস হতে হবে এবং আপনাকে আউটপুট দেয়

4 // from param
someValue // from json file
filename.txt // from first file
other-file-name.data // from second file

লক্ষ্য করার বিষয়টি হ'ল আপনি আলাদা আলাদা সামগ্রীর ধরণের ব্যতীত অন্য কোনও মাল্টিপার্ট ফাইলের মতোই জেএসএন পাঠাচ্ছেন।


1
হাই সোটিরিওস, আমি সেই সুন্দর উদাহরণটি দেখে খুশি হয়েছিলাম এবং তারপরে আমি দেখেছিলাম যে কে এটির প্রস্তাব দেয়, এবং বিঙ্গো! এটি ছিল সোরিরিওস! পরীক্ষা এটি সত্যিই দুর্দান্ত করে তোলে। আমার কাছে একটি জিনিস রয়েছে যা আমাকে বগিং করছে তবে এটি অভিযোগ করে যে অনুরোধটি কোনও মাল্টিপার্ট নয় (500)।
স্টিফেন

এটি এই দাবিটিই assertIsM মাল্টিপার্টআরকুয়েস্ট (servletRequest) ব্যর্থ হয়; আমি সন্দেহ করি কমন্স মাল্টিম্পার্টস রিসোলভারটি কনফিগার করা হয়নি। তবে আমার শিমের একটি লগার লগটিতে প্রদর্শিত হয়।
স্টিফেন

@ শ্রেডিং আমি একটি নিয়ামক ফাইল এবং মডেল অবজেক্টটি আমার নিয়ামককে জসন হিসাবে প্রেরণে আমি এই পদ্ধতিটি গ্রহণ করেছি। কিন্তু মডেল অবজেক্টটি ছুঁড়ে MethodArgumentConversionNotSupportedExceptionমারলে কন্ট্রোলার.আর কোন ধরণের পদক্ষেপ আমি এখানে মিস করেছি? - স্ট্যাকওভারফ্লো.com
ব্রায়ান জে

1
এই উদাহরণটি আমাকে অনেক সাহায্য করেছিল। ধন্যবাদ
কিরণস্বামী

মাল্টিপার্ট POST পদ্ধতি ব্যবহার করে। প্যাচ পদ্ধতি ছাড়া কেউ কি আমাকে এই উদাহরণটি সরবরাহ করতে পারেন?
lalilulelo_1986

16

বসন্তের এমভিসি শোকেস থেকে নেওয়া এই উদাহরণটি একবার দেখুন, এটি উত্স কোডের লিঙ্ক :

@RunWith(SpringJUnit4ClassRunner.class)
public class FileUploadControllerTests extends AbstractContextControllerTests {

    @Test
    public void readString() throws Exception {

        MockMultipartFile file = new MockMultipartFile("file", "orig", null, "bar".getBytes());

        webAppContextSetup(this.wac).build()
            .perform(fileUpload("/fileupload").file(file))
            .andExpect(model().attribute("message", "File 'orig' uploaded successfully"));
    }

}

1
fileUploadপক্ষে হ্রাস করা হয় multipart(String, Object...)
নেক্সা

14

পরিবর্তে পদ্ধতিটি MockMvcRequestBuilders.fileUploadহ্রাস ব্যবহার MockMvcRequestBuilders.multipartকরা হয়।

এটি একটি উদাহরণ:

import static org.hamcrest.CoreMatchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.MultipartFile;


/**
 * Unit test New Controller.
 *
 */
@RunWith(SpringRunner.class)
@WebMvcTest(NewController.class)
public class NewControllerTest {

    private MockMvc mockMvc;

    @Autowired
    WebApplicationContext wContext;

    @MockBean
    private NewController newController;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wContext)
                   .alwaysDo(MockMvcResultHandlers.print())
                   .build();
    }

   @Test
    public void test() throws Exception {
       // Mock Request
        MockMultipartFile jsonFile = new MockMultipartFile("test.json", "", "application/json", "{\"key1\": \"value1\"}".getBytes());

        // Mock Response
        NewControllerResponseDto response = new NewControllerDto();
        Mockito.when(newController.postV1(Mockito.any(Integer.class), Mockito.any(MultipartFile.class))).thenReturn(response);

        mockMvc.perform(MockMvcRequestBuilders.multipart("/fileUpload")
                .file("file", jsonFile.getBytes())
                .characterEncoding("UTF-8"))
        .andExpect(status().isOk());

    }

}

2

আমার জন্য যা কাজ করেছে তা এখানে, আমি পরীক্ষার অধীনে আমার ইমেল নিয়ন্ত্রণকারীকে একটি ফাইল সংযুক্ত করছি। আমি কীভাবে ডেটা পোস্ট করছি সে সম্পর্কে পোস্টম্যানের স্ক্রিনশটটিও দেখুন।

    @WebAppConfiguration
    @RunWith(SpringRunner.class)
    @SpringBootTest(
            classes = EmailControllerBootApplication.class
        )
    public class SendEmailTest {

        @Autowired
        private WebApplicationContext webApplicationContext;

        @Test
        public void testSend() throws Exception{
            String jsonStr = "{\"to\": [\"email.address@domain.com\"],\"subject\": "
                    + "\"CDM - Spring Boot email service with attachment\","
                    + "\"body\": \"Email body will contain  test results, with screenshot\"}";

            Resource fileResource = new ClassPathResource(
                    "screen-shots/HomePage-attachment.png");

            assertNotNull(fileResource);

            MockMultipartFile firstFile = new MockMultipartFile( 
                       "attachments",fileResource.getFilename(),
                        MediaType.MULTIPART_FORM_DATA_VALUE,
                        fileResource.getInputStream());  
                        assertNotNull(firstFile);


            MockMvc mockMvc = MockMvcBuilders.
                  webAppContextSetup(webApplicationContext).build();

            mockMvc.perform(MockMvcRequestBuilders
                   .multipart("/api/v1/email/send")
                    .file(firstFile)
                    .param("data", jsonStr))
                    .andExpect(status().is(200));
            }
        }

পোস্টম্যান অনুরোধ


আপনাকে অনেক ধন্যবাদ আপনার উত্তরটি আমার পক্ষেও কাজ করেছে @ অ্যালফ্রেড
পরমেশ্বর

1

যদি আপনি স্প্রিং 4 / স্প্রিংবুট 1.x ব্যবহার করেন তবে এটি অবশ্যই উল্লেখযোগ্য যে আপনি "পাঠ্য" (জেসন) অংশগুলিও যুক্ত করতে পারেন। এটি মকএমভিসিআরকুয়েস্টবিল্ডার্স.ফাইলআপলোড () ফাইলের মাধ্যমে করা যেতে পারে (মকমল্ট্রিপার্টফাই ফাইল) (যা .multipart()এই সংস্করণে পদ্ধতিটি উপলভ্য নয়) প্রয়োজন:

@Test
public void test() throws Exception {

   mockMvc.perform( 
       MockMvcRequestBuilders.fileUpload("/files")
         // file-part
         .file(makeMultipartFile( "file-part" "some/path/to/file.bin", "application/octet-stream"))
        // text part
         .file(makeMultipartTextPart("json-part", "{ \"foo\" : \"bar\" }", "application/json"))
       .andExpect(status().isOk())));

   }

   private MockMultipartFile(String requestPartName, String filename, 
       String contentType, String pathOnClassPath) {

       return new MockMultipartFile(requestPartName, filename, 
          contentType, readResourceFile(pathOnClasspath);
   }

   // make text-part using MockMultipartFile
   private MockMultipartFile makeMultipartTextPart(String requestPartName, 
       String value, String contentType) throws Exception {

       return new MockMultipartFile(requestPartName, "", contentType,
               value.getBytes(Charset.forName("UTF-8")));   
   }


   private byte[] readResourceFile(String pathOnClassPath) throws Exception {
      return Files.readAllBytes(Paths.get(Thread.currentThread().getContextClassLoader()
         .getResource(pathOnClassPath).toUri()));
   }

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.