空手道:如何测试多部分表单数据端点? [英] Karate: How to test multipart form-data endpoint?

查看:40
本文介绍了空手道:如何测试多部分表单数据端点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在定义如下的控制器中具有文件上载终结点(/document):

@RestController
public class FileUploadController {

    @Autowired
    private PersonCSVReaderService personCSVReaderService;

    @PostMapping(value = "/document", consumes= {MediaType.MULTIPART_FORM_DATA_VALUE})
    public void handleFileUpload3(@RequestPart("file") MultipartFile file, @RequestPart("metadata") DocumentMetadata metadata) {
        System.out.println(String.format("uploading file %s of %s bytes", file.getOriginalFilename(), file.getSize()));
        personCSVReaderService.readPersonCSV(file, metadata);
    }
}

我可以使用Advanced Rest Client(ARC)或Postman来测试此终结点,方法是定义引用"people.csv"文件的文件"部分和指定一些示例元数据JSON的文本部分.

一切正常,我得到了200状态,并且通过service方法将people.csv文件内容写入控制台输出:

uploading file people.csv of 256 bytes
{Address=1, City=2, Date of Birth=6, Name=0, Phone Number=5, State=3, Zipcode=4}
Person{name='John Brown', address='123 Main St.', city='Scottsdale', state='AZ', zipcode='85259', phoneNumber='555-1212', dateOfBirth='1965-01-01'}
Person{name='Jan Black', address='456 University Dr.', city='Atlanta', state='GA', zipcode='30306', phoneNumber='800-1111', dateOfBirth='1971-02-02'}
Person{name='Mary White', address='789 Possum Rd.', city='Nashville', state='TN', zipcode='37204', phoneNumber='888-2222', dateOfBirth='1980-03-03'}

现在,我想将其作为自动空手道测试来运行.我已经指定了MockConfig:

@Configuration
@EnableAutoConfiguration
@PropertySource("classpath:application.properties")
public class MockConfig {

    // Services ...
    @Bean
    public PersonCSVReaderService personCSVReaderService() {
        return new PersonCSVReaderService();
    }

    // Controllers ...
    @Bean
    public FileUploadController fileUploadController() {
        return new FileUploadController();
    }
}

我在类路径中也有一个MockSpringMvcServlet,而我的karate-config.js是:

function fn() {    
   var env = karate.env; // get system property 'karate.env'
   if (!env) {
      env = 'dev';
   }
   karate.log('karate.env system property was:', env);

   var config = {
     env: env,
     myVarName: 'someValue',
     baseUrl: 'http://localhost:8080'
   }

   if (env == 'dev') {
      var Factory = Java.type('MockSpringMvcServlet');
      karate.configure('httpClientInstance', Factory.getMock());
      //var result = karate.callSingle('classpath:demo/headers/common-noheaders.feature', config);
   } else if (env == 'stg') {
      // customize
   } else if (env == 'prod') {
      // customize
   }

   return config;
}

其他空手道测试可以使用模拟servlet正常运行.

但是,当我尝试此测试来测试/document端点时:

Feature: file upload end-point

  Background:
    * url baseUrl
    * configure lowerCaseResponseHeaders = true

  Scenario: upload file
    Given path '/document'
    And header Content-Type = 'multipart/form-data'
    And multipart file file =  { read: 'people.csv', filename: 'people.csv', contentType: 'text/csv' }
    And multipart field metadata = { name: "joe", description: "stuff" }
    When method post
    Then status 200

我收到此错误:

16:14:42.674 [main] INFO  com.intuit.karate - karate.env system property was: dev 
16:14:42.718 [main] INFO  o.s.mock.web.MockServletContext - Initializing Spring DispatcherServlet ''
16:14:42.719 [main] INFO  o.s.web.servlet.DispatcherServlet - Initializing Servlet ''
16:14:43.668 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$a4c7d08f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
16:14:43.910 [main] INFO  o.h.validator.internal.util.Version - HV000001: Hibernate Validator 6.0.14.Final
16:14:44.483 [main] INFO  o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
16:14:44.968 [main] INFO  o.s.b.a.e.web.EndpointLinksResolver - Exposing 2 endpoint(s) beneath base path '/actuator'
16:14:45.006 [main] INFO  o.s.web.servlet.DispatcherServlet - Completed initialization in 2287 ms
16:14:45.066 [main] INFO  c.i.k.mock.servlet.MockHttpClient - making mock http client request: POST - http://localhost:8080/document
16:14:45.085 [main] DEBUG c.i.k.mock.servlet.MockHttpClient - 
1 > POST http://localhost:8080/document
1 > Content-Type: multipart/form-data

16:14:45.095 [main] ERROR com.intuit.karate - http request failed: null
file-upload.feature:13 - null
HTML report: (paste into browser to view) | Karate version: 0.9.2

我只能假设参数与我的端点期望的不符-我从未以调试模式进入端点.

我尝试过:

    And multipart file file =  read('people.csv')
    And multipart field metadata = { name: "joe", description: "stuff" }

但这也不是首发.

我做错了什么? people.csv与fileupload.feature位于同一文件夹中,因此我假设它正在查找文件.我还查看了以下空手道演示项目中的upload.feature文件:

空手道演示项目upload.feature

但是我无法使其正常工作.任何帮助表示赞赏.预先感谢.

邮递员请求如下所示:

编辑更新:

我无法获得建议的答案.

以下是功能文件:

Feature: file upload

  Background:
    * url baseUrl
    * configure lowerCaseResponseHeaders = true

  Scenario: upload file
    Given path '/document'
    And header Content-Type = 'multipart/form-data'
    * def temp = karate.readAsString('people.csv')
    * print temp
    And multipart file file =  { value: '#(temp)', filename: 'people.csv', contentType: 'text/csv' }
    And multipart field metadata = { value: {name: 'joe', description: 'stuff'}, contentType: 'application/json' }
    When method post
    Then status 200

这是运行该测试的控制台输出:

09:27:22.051 [main] INFO  com.intuit.karate - found scenario at line: 7 - ^upload file$
09:27:22.156 [main] INFO  com.intuit.karate - karate.env system property was: dev 
09:27:22.190 [main] INFO  o.s.mock.web.MockServletContext - Initializing Spring DispatcherServlet ''
09:27:22.190 [main] INFO  o.s.web.servlet.DispatcherServlet - Initializing Servlet ''
09:27:23.084 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$a4c7d08f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
09:27:23.327 [main] INFO  o.h.validator.internal.util.Version - HV000001: Hibernate Validator 6.0.14.Final
09:27:23.896 [main] INFO  o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
09:27:24.381 [main] INFO  o.s.b.a.e.web.EndpointLinksResolver - Exposing 2 endpoint(s) beneath base path '/actuator'
09:27:24.418 [main] INFO  o.s.web.servlet.DispatcherServlet - Completed initialization in 2228 ms
09:27:24.435 [main] INFO  com.intuit.karate - [print] Name,Address,City,State,Zipcode,Phone Number,Date of Birth
John Brown,123 Main St.,Scottsdale,AZ,85259,555-1212,1965-01-01
Jan Black,456 University Dr.,Atlanta,GA,30306,800-1111,1971-02-02
Mary White,789 Possum Rd.,Nashville,TN,37204,888-2222,1980-03-03

09:27:24.482 [main] INFO  c.i.k.mock.servlet.MockHttpClient - making mock http client request: POST - http://localhost:8080/document
09:27:24.500 [main] DEBUG c.i.k.mock.servlet.MockHttpClient - 
1 > POST http://localhost:8080/document
1 > Content-Type: multipart/form-data

09:27:24.510 [main] ERROR com.intuit.karate - http request failed: null
file-upload.feature:14 - null
HTML report: (paste into browser to view) | Karate version: 0.9.2

注意:people.csv文件读取成功并在控制台中打印.

解决方案

功能:上传CSV

背景:并且def admin = read('classpath:com/project/data/adminLogin.json')

场景: 给定url baseUrl

标题标头=管理员令牌

多部分文件residentDetails = {读取:"classpath:com/project/data/ResidentApp_Details.csv",文件名:"ResidentApp_Details.csv"}

方法POST时

然后状态为200

注意:仅添加多一行,即,多部分文件residentDetails = {读取:"classpath:com/project/data/ResidentApp_Details.csv",文件名:"ResidentApp_Details.csv"}}

I have an file upload endpoint (/document) in a controller defined as follows:

@RestController
public class FileUploadController {

    @Autowired
    private PersonCSVReaderService personCSVReaderService;

    @PostMapping(value = "/document", consumes= {MediaType.MULTIPART_FORM_DATA_VALUE})
    public void handleFileUpload3(@RequestPart("file") MultipartFile file, @RequestPart("metadata") DocumentMetadata metadata) {
        System.out.println(String.format("uploading file %s of %s bytes", file.getOriginalFilename(), file.getSize()));
        personCSVReaderService.readPersonCSV(file, metadata);
    }
}

I can test this endpoint using Advanced Rest Client (ARC) or Postman by defining the "file" part referencing the people.csv file and a text part specifying some sample metadata JSON.

Everything works fine and I get a 200 status back with the people.csv file contents being written to the console output by the service method:

uploading file people.csv of 256 bytes
{Address=1, City=2, Date of Birth=6, Name=0, Phone Number=5, State=3, Zipcode=4}
Person{name='John Brown', address='123 Main St.', city='Scottsdale', state='AZ', zipcode='85259', phoneNumber='555-1212', dateOfBirth='1965-01-01'}
Person{name='Jan Black', address='456 University Dr.', city='Atlanta', state='GA', zipcode='30306', phoneNumber='800-1111', dateOfBirth='1971-02-02'}
Person{name='Mary White', address='789 Possum Rd.', city='Nashville', state='TN', zipcode='37204', phoneNumber='888-2222', dateOfBirth='1980-03-03'}

Now, I want to run this as an automated Karate test. I have specified a MockConfig :

@Configuration
@EnableAutoConfiguration
@PropertySource("classpath:application.properties")
public class MockConfig {

    // Services ...
    @Bean
    public PersonCSVReaderService personCSVReaderService() {
        return new PersonCSVReaderService();
    }

    // Controllers ...
    @Bean
    public FileUploadController fileUploadController() {
        return new FileUploadController();
    }
}

I also have a MockSpringMvcServlet in the classpath and my karate-config.js is :

function fn() {    
   var env = karate.env; // get system property 'karate.env'
   if (!env) {
      env = 'dev';
   }
   karate.log('karate.env system property was:', env);

   var config = {
     env: env,
     myVarName: 'someValue',
     baseUrl: 'http://localhost:8080'
   }

   if (env == 'dev') {
      var Factory = Java.type('MockSpringMvcServlet');
      karate.configure('httpClientInstance', Factory.getMock());
      //var result = karate.callSingle('classpath:demo/headers/common-noheaders.feature', config);
   } else if (env == 'stg') {
      // customize
   } else if (env == 'prod') {
      // customize
   }

   return config;
}

Other karate tests run ok using the mock servlet.

However, when I try this test to test the /document endpoint:

Feature: file upload end-point

  Background:
    * url baseUrl
    * configure lowerCaseResponseHeaders = true

  Scenario: upload file
    Given path '/document'
    And header Content-Type = 'multipart/form-data'
    And multipart file file =  { read: 'people.csv', filename: 'people.csv', contentType: 'text/csv' }
    And multipart field metadata = { name: "joe", description: "stuff" }
    When method post
    Then status 200

I get this error:

16:14:42.674 [main] INFO  com.intuit.karate - karate.env system property was: dev 
16:14:42.718 [main] INFO  o.s.mock.web.MockServletContext - Initializing Spring DispatcherServlet ''
16:14:42.719 [main] INFO  o.s.web.servlet.DispatcherServlet - Initializing Servlet ''
16:14:43.668 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$a4c7d08f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
16:14:43.910 [main] INFO  o.h.validator.internal.util.Version - HV000001: Hibernate Validator 6.0.14.Final
16:14:44.483 [main] INFO  o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
16:14:44.968 [main] INFO  o.s.b.a.e.web.EndpointLinksResolver - Exposing 2 endpoint(s) beneath base path '/actuator'
16:14:45.006 [main] INFO  o.s.web.servlet.DispatcherServlet - Completed initialization in 2287 ms
16:14:45.066 [main] INFO  c.i.k.mock.servlet.MockHttpClient - making mock http client request: POST - http://localhost:8080/document
16:14:45.085 [main] DEBUG c.i.k.mock.servlet.MockHttpClient - 
1 > POST http://localhost:8080/document
1 > Content-Type: multipart/form-data

16:14:45.095 [main] ERROR com.intuit.karate - http request failed: null
file-upload.feature:13 - null
HTML report: (paste into browser to view) | Karate version: 0.9.2

I can only assume that the arguments did not conform to what my endpoint was expecting - I never entered the endpoint in debug mode.

I tried this:

    And multipart file file =  read('people.csv')
    And multipart field metadata = { name: "joe", description: "stuff" }

But that was a non-starter as well.

What am I doing wrong? The people.csv is in the same folder as fileupload.feature, so I am assuming it is finding the file. I also looked at upload.feature file in the Karate demo project given here:

Karate demo project upload.feature

But I could not make it work. Any help appreciated. Thanks in advance.

The Postman request looks like this:

EDIT UPDATE:

I could not get the suggested answer to work.

Here is the feature file:

Feature: file upload

  Background:
    * url baseUrl
    * configure lowerCaseResponseHeaders = true

  Scenario: upload file
    Given path '/document'
    And header Content-Type = 'multipart/form-data'
    * def temp = karate.readAsString('people.csv')
    * print temp
    And multipart file file =  { value: '#(temp)', filename: 'people.csv', contentType: 'text/csv' }
    And multipart field metadata = { value: {name: 'joe', description: 'stuff'}, contentType: 'application/json' }
    When method post
    Then status 200

And here is the console output from running that test:

09:27:22.051 [main] INFO  com.intuit.karate - found scenario at line: 7 - ^upload file$
09:27:22.156 [main] INFO  com.intuit.karate - karate.env system property was: dev 
09:27:22.190 [main] INFO  o.s.mock.web.MockServletContext - Initializing Spring DispatcherServlet ''
09:27:22.190 [main] INFO  o.s.web.servlet.DispatcherServlet - Initializing Servlet ''
09:27:23.084 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$a4c7d08f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
09:27:23.327 [main] INFO  o.h.validator.internal.util.Version - HV000001: Hibernate Validator 6.0.14.Final
09:27:23.896 [main] INFO  o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
09:27:24.381 [main] INFO  o.s.b.a.e.web.EndpointLinksResolver - Exposing 2 endpoint(s) beneath base path '/actuator'
09:27:24.418 [main] INFO  o.s.web.servlet.DispatcherServlet - Completed initialization in 2228 ms
09:27:24.435 [main] INFO  com.intuit.karate - [print] Name,Address,City,State,Zipcode,Phone Number,Date of Birth
John Brown,123 Main St.,Scottsdale,AZ,85259,555-1212,1965-01-01
Jan Black,456 University Dr.,Atlanta,GA,30306,800-1111,1971-02-02
Mary White,789 Possum Rd.,Nashville,TN,37204,888-2222,1980-03-03

09:27:24.482 [main] INFO  c.i.k.mock.servlet.MockHttpClient - making mock http client request: POST - http://localhost:8080/document
09:27:24.500 [main] DEBUG c.i.k.mock.servlet.MockHttpClient - 
1 > POST http://localhost:8080/document
1 > Content-Type: multipart/form-data

09:27:24.510 [main] ERROR com.intuit.karate - http request failed: null
file-upload.feature:14 - null
HTML report: (paste into browser to view) | Karate version: 0.9.2

Note: people.csv file reads successfully and prints in console.

解决方案

Feature: upload csv

Background: And def admin = read('classpath:com/project/data/adminLogin.json')

Scenario: Given url baseUrl

And header Authorization = admin.token

And multipart file residentDetails = { read:'classpath:com/project/data/ResidentApp_Details.csv', filename: 'ResidentApp_Details.csv' }

When method POST

Then status 200

Note: Add only one extra line i.e And multipart file residentDetails = { read:'classpath:com/project/data/ResidentApp_Details.csv', filename: 'ResidentApp_Details.csv' }

这篇关于空手道:如何测试多部分表单数据端点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆