spring-cloud-contract

Spring Cloud Contract with multiple requestparts


I'm trying to write a contract to test the following providers endpoint

@PostMapping(value = "/api/{id}/addFiles", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ResponseEntity<Void> addFiles(@PathVariable(value = "id") String id, @RequestPart("name") String name, @RequestPart("test") String test, @RequestPart("files") MultiPartFile[] files)

I'm struggling to write a contract that works with multiple RequestParts such as this. If I change the two String RequestParts to RequestParams I can get the test to pass with the following contract:

Contract.make {
  description "Add Files"
  request {
    urlPath("/api/idString/addFiles") {
      queryParameters {
        parameter 'name': value(consumer(regex(nonEmpty())), producer('name'))
        parameter 'test': value(consumer(regex(nonEmpty())), producer('test'))
      }
    }
    method POST()
    headers {
      contentType multipartFormData()
    }
    multipart(
      files: named(
        name: value(consumer(regex(nonEmpty())), producer('fileName')),
        content: value(consumer(regex(nonEmpty())), producer('fileContent'))
      )
    )
  }
  response {
    status ACCEPTED()
  }
}

But is there a way of writing this contract whilst keeping everything as RequestParts? Nothing I've tried so far has come close to working!


Solution

  • Answering my own question since I realised the small error I had been making. The following contract appears to work, I had tried something similar but had not included the square brackets inside the multipart:

    Contract.make {
      description "Add Files"
      request {
        urlPath("/api/idString/addFiles")
        method POST()
        headers {
          contentType multipartFormData()
        }
        multipart([
          name: named(
            name: value(consumer(regex(nonEmpty())), producer('name')),
            content: value(consumer(regex(nonEmpty())), producer('name'))
          ),
          test: named(
            name: value(consumer(regex(nonEmpty())), producer('test')),
            content: value(consumer(regex(nonEmpty())), producer('testName'))
          ),
          files: named(
            name: value(consumer(regex(nonEmpty())), producer('fileName')),
            content: value(consumer(regex(nonEmpty())), producer('fileContent'))
          )
        ])
      }
      response {
        status ACCEPTED()
      }
    }