首页 > 解决方案 > Spock,捕获参数并在测试的其他部分使用它们

问题描述

所以我想捕获传递给模拟的参数并设置它们,以便我的测试中的其他东西可以使用它们

class FileServiceSpec extends Specification {

  @Shared
  FileEntity originalFileUploadEntity

  def fileRepository = Mock(FileRepository)
  def fileStorageClient = Mock(FileStorageClient)
  def fileConverter = Mock(FileConverter)
  def fileMapper = new FileMapperImpl()
  def fileService = new FileService(fileRepository, fileStorageClient, fileConverter, fileMapper)

      def"upload offline canvas file requires conversion"(){
    given: " a file that requires conversions"
    def file = fileUploadRequest("test.pptx")
    def content = "dGVzdCBmaWxl"
    def taskId = "100"

    FileEntity convertedFileUploadEntity
    FileEntity originalFileUploadEntity

    when:
    def resp = fileService.uploadOfflineCanvasUploadAndConvertedUpload(file, content, taskId);

    then:
    1 * fileConverter.convertPptxToPdf(*_) >> Base64.getDecoder().decode("convertedpdfcontent");

    //the converted file is uploaded
    1 * fileStorageClient.uploadFile(_, Base64.getDecoder().decode("convertedpdfcontent" )) >> {args ->
      convertedFileUploadEntity = FileEntity.class.cast(args[0])
      assert FileEntity.class.cast(args[0]).fileName == "test.pdf"
      assert FileEntity.class.cast(args[0]).entityName == "offline-canvas-converted-upload"
    };
    //the original file is uploaded
    1 * fileStorageClient.uploadFile(_, Base64.getDecoder().decode(content )) >> {args ->
      originalFileUploadEntity = FileEntity.class.cast(args[0])
      assert FileEntity.class.cast(args[0]).fileName == "test.pptx"
      assert FileEntity.class.cast(args[0]).entityName == "offline-canvas-upload"
    };
  }

如您所见,我能够捕获参数并将其值设置为如下 originalFileUploadEntity = FileEntity.class.cast(args[0])。但是,一旦我退出 lambda,该值再次变为 null,因此在第一个方法捕获中,我设置它并且我可以在调试时看到它,但是在第二个方法参数捕获中,我在第一个方法捕获中设置的属性是现在为空

标签: groovyspock

解决方案


以这种方式它必须工作:

def "upload offline canvas file requires conversion"() {
    given: " a file that requires conversions"
    def file = fileUploadRequest("test.pptx")
    def content = "dGVzdCBmaWxl"
    def taskId = "100"

    def expectedDecodedContent = Base64.getDecoder().decode("convertedpdfcontent")
    FileEntity convertedFileUploadEntity = null
    FileEntity originalFileUploadEntity = null

    when:
    def resp = fileService.uploadOfflineCanvasUploadAndConvertedUpload(file, content, taskId);

    then:
    1 * fileConverter.convertPptxToPdf(*_) >> expectedDecodedContent;

    1 * fileStorageClient.uploadFile(_, expectedDecodedContent) >> { convertedFileUploadEntity = it[0] as FileEntity }
    convertedFileUploadEntity.fileName == "test.pdf"
    convertedFileUploadEntity.entityName == "offline-canvas-converted-upload"

    1 * fileStorageClient.uploadFile(_, Base64.getDecoder().decode(content)) >> { originalFileUploadEntity = it[0] as FileEntity }
    originalFileUploadEntity.fileName == "test.pptx"
    originalFileUploadEntity.entityName == "offline-canvas-upload"
}

如果uploadFile方法返回FileEntity实例,那么它在您的情况下不起作用,因为您没有从闭包中返回它,而是使用断言而不是它。

在此示例中,闭包返回值convertedFileUploadEntity

1 * fileStorageClient.uploadFile(_, expectedDecodedContent) >> { 
    convertedFileUploadEntity = it[0] as FileEntity 
}

因为它与以下内容相同:

1 * fileStorageClient.uploadFile(_, expectedDecodedContent) >> {
    convertedFileUploadEntity = it[0] as FileEntity
    return convertedFileUploadEntity 
}

但在此示例中,闭包不会返回它:

1 * fileStorageClient.uploadFile(_, expectedDecodedContent) >> { 
    convertedFileUploadEntity = it[0] as FileEntity
    assert convertedFileUploadEntity.fileName == "test.pdf" 
}

推荐阅读