ScalaCheck:使用任意类型

时间:2018-05-18 13:08:06

标签: scala scalatest scalacheck

我已实现以下功能:

/**
  * Returns a function h , which is the composition of the functions f and g.
  */
def compose[A, B, C](g: B => C, f: A => B): A => C = f.andThen(g)

我正试图用ScalaCheck来测试它。我可以生成以下测试,编译并传递:

import org.scalatest.prop.PropertyChecks
import org.scalatest.{FlatSpec, Matchers}

class ComposeSpec extends FlatSpec with Matchers with PropertyChecks {

  "Compose" should "return a function h , which is the composition of the 
functions f and g" in {

    forAll { (a: Int, g: Int => Int, f: Int => Int) =>
      compose(g, f)(a) should be(g(f(a)))
    }

    forAll { (a: String, g: Double => Int, f: String => Double) =>
      compose(g, f)(a) should be(g(f(a)))
    }
  }
}

但是,如您所见,我正在使用已定义的类型生成任意函数,并且还将参数a的类型与函数f的输入类型进行匹配。我想做的事情是这样的:

forAll { (a: A, g: B => C, f: A => B) =>
  compose(g, f)(a) should be(g(f(a)))
}

但是我不知道它的语法,也不知道它是否可能。你能帮帮我吗?

1 个答案:

答案 0 :(得分:3)

scalatest website可以说forAll

  

需要提供隐式Arbitrary生成器和Shrink对象   for forAll方法将每行数据传递给每个参数   类型。 ScalaCheck提供了许多隐式Arbitrary生成器   常见类型,例如IntStringList[Float]等   org.scalacheck.Arbitrary个伴侣对象。只要你使用类型   ScalaCheck已经为其提供了隐式Arbitrary生成器,   你不用担心它们。对于Shrink个对象也是如此   由ScalaCheck的org.scalacheck.Shrink伴随对象提供。最   通常你可以简单地将属性函数传递给forAll,然后将其传递给forAll   编译器将获取ScalaCheck提供的隐式值。

很遗憾,您无法使用Arbitrary检查每种可能的类型,因为每种可能的类型都没有隐式的Shrinkdef checkComposeForAll[A : Arbitrary : Shrink, B : Arbitrary : Shrink, C : Arbitrary : Shrink]() = { forAll { (a: A, g: B => C, f: A => B) => compose(g, f)(a) should be(g(f(a))) } } checkComposeForAll[Int, Int, Int]() checkComposeForAll[String, String, String]() checkComposeForAll[List[Int], Double, Int]() // ... etc, check a bunch of types ... 对象。生成任意类型的任意对象似乎是不可能的。

你能做的最好的事情就是:

status, status_token