Search code examples
scalatestingscalatest

Scalatest: Combine Assertions


I've just started using WordSpec and I've come across a problem I can't get around.

I'd like to assert on two separate values in one unit test. Suppose I have val result1 and val result2, I need the first to take on a particular value AND the second to take on another particular value.

This would be really easy if it was possible to concatenate/reduce/fold on assertions but I don't think I can. Perhaps something like this:

result1 should be (1) ++ result2 should be (2)

The result would be a new assertion which is only true if both assertions are true.

If I write them as below, it will only take the last value.

result1 should be (1)
result2 should be (2)

Does anyone know a way around this?


Solution

  • For ScalaTest 3.0.1, the two options I see are:

    1.) Use a tuple (as @krzysztof-atłasik has commented)

    (result1, result2) should be (1, 2)
    

    2.) Use a Checkpoint

    val cp = new Checkpoint()
    
    cp { result1 should be (1) }
    cp { result2 should be (2) }
    
    cp.reportAll()
    

    class Checkpoint, which enables multiple assertions to be performed within a test, with any failures accumulated and reported together at the end of the test.

    -- ScalaTest's Checkpoints scaladoc

    Personally, I like Checkpoint because it provides an arguably better separation on what is being asserted. However, a potential downside I found is that unlike should be (x), which returns Assertion, Checkpoint#reportAll() returns Unit. I had a method that needed to return Assertion and the work around I used was to return org.scalatest.Succeeded.

    e.g.,

    def someMethod(): Assertion = {
      ...
      cp.reportAll()
      Succeeded
    }