Search code examples
scalatestingscalatest

Testing Right[Seq[MyClass]] and properties


I am trying to implement a test with ScalaTest (WordSpecLike, MustMatchers) that verify if an Either[Seq[Error], Seq[Value]] contains one value and if the value has some specific attributes.

Ideally I would like to have something like:

val result:Either[Seq[Error], Seq[Value]] = ...
result.value must contain { _ have (
  'prop ("value")
)}

But this does not compile and I have no clue on how to achieve this kind of matching.

Is there documentation on deep tests or some best practices for that?


Solution

  • Inspectors enable assertions to be made about collections, and in combination with EitherValues, as suggested by @LuisMiguelMejíaSuárez, and checking arbitrary properties with have, the following syntax is possible

    atLeast(1, result.right.value) must have ('prop ("value"))
    

    Here is a working example

    class Value(val foo: String, val bar: Int) {
      def isTooLong: Boolean = foo.length > 2
    }
    
    class StackOverflowSpec extends WordSpec with MustMatchers with EitherValues with Inspectors {
      "Result" when {
        "Right" should {
          "have property" in {
            val result: Either[Seq[Error], Seq[Value]] = Right(Seq(new Value("aa", 11), new Value("bbb", 42)))
            atLeast(1, result.right.value) must have ('tooLong (true), 'bar (42) )
          }
        }
      }
    }
    

    Alternatively try pattern matching on result and passing the property predicate to Seq.exists like so

    class Value(val foo: String, val bar: String) {
      def isTooLong: Boolean = foo.length > 2
    }
    
    class StackOverflowSpec extends WordSpec with MustMatchers {
      "Result" when {
        "Right" should {
          "have property" in {
            val result: Either[Seq[Error], Seq[Value]] = Right(Seq(new Value("a", "b"), new Value("ccc", "ddd")))
            result match {
              case Left(seq) => fail
              case Right(seq) => seq.exists(_.isTooLong) must be(true)
            }
          }
        }
      }
    }