我想找出哪一种风格最适合这种情况
我有一个图像模型
case class Image(
id: Int,
name: String,
title: String,
permalink: String,
url: String
)
我有一个TestHelper对象,它可以帮助我编写测试,因为它允许我创建随机图像对象。
package utils
import models.Pet
import scala.util.Random
object TestHelper {
val random = new Random()
def randomId = random.nextInt(Integer.MAX_VALUE)
val nameList: List[String] = List("Joycelyn", "Shaunte", "Aurelio", "Jeane", "Carline", "Major", "Shawanna", "Hayden", "Benjamin", "Roxy", "Ardelia", "Yanira", "Tilda", "Claude", "Jonah", "Ilse", "Kieth", "Elmira", "Reid", "Bethann", "Catherine", "Yasuko", "Kia", "Merri", "Ethelyn", "Mallory", "Eustolia", "Matt", "Lynelle", "Christi", "Alane", "Miles", "Ressie", "Darryl", "Kathy", "Hiedi", "Kacy", "Cecila", "Tamar", "Dwayne", "Charlette", "Wanetta", "Sonja", "Celine", "Vina", "Teresa", "Dagny", "Debera", "Doreatha", "Wilda")
def randomImage: Image = {
var id = randomId
var name = nameList(random.nextInt(nameList.length))
var title = name
var permalink = name.toLowerCase
var logoUrl = s"https://www.images.com/${permalink}"
Image(id, name, title, permalink, logoUrl)
}
}
但我知道,如果我想用函数式写作,我应该避免使用var
。如果我不多次使用字段name
,那么用def
来替换所有的var
就足够了,但是由于我需要重复这个值,所以我不知道如何用函数样式编写这个值。
发布于 2018-04-26 15:58:16
在这种情况下,您可以简单地将所有本地var
替换为val
,因为您无论如何都不会变异var
s。
发布于 2018-04-26 15:22:47
看看我们的一个谎言(无耻的免责声明)。
util-
https://github.com/outworkers/util/blob/develop/util-samplers
它使用宏导航案例类的结构并生成适当的示例。它不是一颗神奇的子弹,但它大多数时候都会处理很多事情,而且它也会在可能的情况下生成有意义的数据。
例如,如果该字段被称为name,您将得到"Peter“样式的结果。它还与Scalacheck完全兼容,但总体上非常基本,具有一个非常简单的宏。通过让我写它来保证它的简单性。
val imageGenerator = Sample.generator[Image]
implicit val imageArb = Sample.arbitrary[Image]
你可以直接把它插入到功能检查程序中。
forAll { img: Image => ....
}
如果你根本不想要斜交刀,只需使用以下基本方法:
import com.outworkers.util.samplers._
class MyTest extends FlatSpec {
it should "upload an image to S3" in {
val image = gen[Image]
val images = genList[Image](25)
}
}
如果您无法生成类型或宏抱怨,只需自己编写一个采样器。在大多数情况下,你会有一个类似的特征或对象来持有他们的全部。
object ExtraSamples {
implicit val cantAutomateThis: Sample[java.net.Bla] = new Sample[java.net.Bla] {
override def sample: java.net.Bla = // in here you fill it in manuall....
}
}
然后,如果您有一个带有case class
字段的java.net.Bla
,您只需在执行gen
的地方使用import ExtraSamples._
,您的手动实现将用于构造更复杂的实现。这就是为什么你可以支持任何不受支持的东西。
scalacheck-shapeless
对于相同的问题,这是一个不同的处理方法,但是它使用的不是宏,而是使用自动类型类型实例派生功能。它与util-samplers
的方法并没有太大的不同,但代码可能稍微复杂一些,但级别更高。
https://github.com/alexarchambault/scalacheck-shapeless
import org.scalacheck.ScalacheckShapeless._
// If you defined:
// case class Foo(i: Int, s: String, blah: Boolean)
// case class Bar(foo: Foo, other: String)
// sealed trait Base
// case class BaseIntString(i: Int, s: String) extends Base
// case class BaseDoubleBoolean(d: Double, b: Boolean) extends Base
// then you can now do
implicitly[Arbitrary[Foo]]
implicitly[Arbitrary[Bar]]
implicitly[Arbitrary[Base]]
我从来没有做过横向比较,他们也不打算互相竞争。第一个是非常快速和轻量级的,并且开销最小,因为它只是一个宏,不成形的宏更复杂,编译时间更长,但是它可能在自动生成类型方面更高级。
发布于 2018-04-26 15:20:22
为此您可以使用ScalaCheck。ScalaCheck是函数语言Haskell的库QuickCheck的一个端口,它允许您以函数样式编写随机测试示例生成器。
https://stackoverflow.com/questions/50046611
复制相似问题