3

Javaで記述されたドメインオブジェクト用のさまざまなHamcrestマッチャーがあります。私は今Scalaに移動しており、specs2テストのコンテキストでこれらの既存のマッチャーを再利用したいと思います。

クラスFooのHamcrestマッチャーを考えると:

public class FooMatcher extends TypeSafeMatcher[Foo] {
...
}

このように使用できるようにしたいと思います。

val myFooMatcher = new FooMatcher(...)
foo must match (myFooMatcher)
foos must contain (myFooMatcher1, myFooMatcher2)

等々。

Specs2には反対の、Matcher [T]トレイトのorg.hamcrest.Matcherへのアダプターがあるようですが、私はその逆を探しています。

何か案は?

4

1 に答える 1

1

これを機能させるには、暗黙的な変換を 1 つ追加する必要があります。

import org.hamcrest._
import org.specs2.matcher.MustMatchers._

implicit def asSpecs2Matcher[T](hamcrest: org.hamcrest.TypeSafeMatcher[T]):     
  org.specs2.matcher.Matcher[T] = {

  def koMessage(a: Any) = {
    val description = new StringDescription
    description.appendValue(a)
    hamcrest.describeTo(description)
    description.toString 
  }
  (t: T) => (hamcrest.matches(t), koMessage(t))  
}

実際に見てみましょう:

case class Foo(isOk: Boolean = true)

// a Hamcrest matcher for Foo elements
class FooMatcher extends TypeSafeMatcher[Foo] {
  def matchesSafely(item: Foo): Boolean    = item.isOk
  def describeTo(description: Description) = description.appendText(" is ko")
}

// an instance of that matcher
def beMatchingFoo = new FooMatcher

// this returns a success
Foo() must beMatchingFoo

// this returns a failure
Foo(isOk = false) must beMatchingFoo

// this is a way to test that some elements in a collection have
// the desired property
Seq(Foo()) must have oneElementLike { case i => i must beMatchingFoo }

// if you have several matchers you want to try out
Seq(Foo()) must have oneElementLike { case i => 
  i must beMatchingFoo and beMatchingBar 
}
于 2012-10-30T00:18:41.083 に答える