代码之家  ›  专栏  ›  技术社区  ›  Andreas Neumann

带未来结果的规范2数据表

  •  1
  • Andreas Neumann  · 技术社区  · 10 年前

    我正在努力解决以下问题: 我有一个方法返回 未来[结果] 哪里 后果 是我想用specs2中的数据表行检查的内容。

    据我所知,下面的代码每次都会阻塞,并等待结果可用。

    def getDataForInput(input: String) : Future[Result]
    
    def myTest =
     "input"   |  "expectedResult" |>
      "a"    !  123                |
      "b"      !  0                | {
        (input, result) => getDataForInput input must( beEqualTo(result).await )
      }
    

    通常,我希望异步进行所有调用,然后使用 未来.序列 转换 顺序[未来[结果]] 未来〔顺序〔结果〕〕 然后运行测试。

    有没有一种理智的方法可以做到这一点?

    1 回复  |  直到 10 年前
        1
  •  2
  •   Eric    10 年前

    没有 容易的 要做到这一点,你需要解构和重建一些东西

    type RowResult = (Seq[String], Result)
    
    val table =
      "input"  |  "expectedResult" |
       "123"   !  123              |
       "0"     !  1                |
       "0"     !  0
    
    // get a Future containing all rows and results
    val results: Future[List[RowResult]] = table.rows.toList.traverseU { row =>
      getDataForInput(row.t1).map { i => 
        (row.showCells, (i must beEqualTo(row.t2)).toResult) 
      }
    }
    
    // check the results
    results must beSuccessfulTable(table.titles).await
    

    这使用了一个自定义的匹配器,这会使表格显示得更不美观

    // the TextTable does an even display of columns
    import org.specs2.text.TextTable
    
    def beSuccessfulTable(titles: Seq[String]): Matcher[List[RowResult]] = { values: List[RowResult] =>
      val overallSuccess = values.map(_._2).reduce(_ and _).isSuccess
      val headers = if (overallSuccess) titles else Seq("")++titles++Seq("")
      val table = TextTable(headers, values.map(resultLine.tupled))
      (overallSuccess, table.show)
    }
    
    // helper method
    def resultLine = (line: Seq[String], result: Result) => {
      val message = if (result.isSuccess) "" else result.message
      result.status +: line :+ message
    }