8

I am new to Scala and Spec2.

I would like to create the following test but I get an error from the compiler.

Here is the test I would like to write

import org.specs2.mutable._
import org.specs2.specification._
import org.specs2.matcher._
import org.specs2.matcher.MatchResult

class SimpleParserSpec extends Specification {

"SimpleParser" should {

val parser = new SimpleParser()

  "work with basic tweet" in {
      val tweet = """{"id":1,"text":"foo"}"""
      parser.parse(tweet) match {
        case Some(parsed) => {
                                parsed.text must be_==("foo")
                                parsed.id must be_==(1)
                              }
        case _ =>  failure("didn't parse tweet") 
      }
    }
  }
}

I get the error: C:\Users\haques\Documents\workspace\SBT\jsonParser\src\test\scala\com\twitter\sample\simpleSimpleParserSpec.scala:17: could not find implicit value for evidence parameter of type org.specs2.execute.AsResult[Object]

Regards,

Shohidul

shodz
  • 194
  • 2
  • 12

3 Answers3

8

The compiler produces an error here because he tries to unify a MatchResult[Option[Parsed]] with a failure of type Result. They unify as Object and the compiler can't find an AsResult typeclass instance for that. You can fix your example by providing another MatchResult for the failed case:

parser.parse(tweet) match {
  case Some(parsed) => {
    parsed.text must be_==("foo")
    parsed.id must be_==(1)
  }
  case _ =>  ko("didn't parse tweet")
}

The ok and ko methods are the equivalent of success and failure but are MatchResults instead of being Results.

Eric
  • 15,249
  • 36
  • 60
2

Would better write it as following:

"work with basic tweet" in {
  val tweet = """{"id":1,"text":"foo"}"""
  parser.parse(tweet) aka "parsed value" must beSome.which {
    case parsed => parsed.text must_== "foo" and (
      parsed.id must_== 1)
  }
}
cchantep
  • 8,797
  • 3
  • 25
  • 39
  • Your code example works fine. But, is there a way to use failure() and must be_==() at the same time when using match as posted in the original question? – shodz Aug 13 '14 at 17:08
  • The `failure` is useless there, as if result doesn't match `beSome`, specs will indicate expectation is not successful. – cchantep Aug 13 '14 at 17:47
  • The method I was looking for was ko for failure. For success() you would use ok. It is written in the response below. Using ok and ko for me would make the code easier to write. – shodz Aug 14 '14 at 08:35
  • So you'd better use something else than specd. It's not the way it's supposed to be used. There handling failure with ko is just useless. – cchantep Aug 14 '14 at 08:58
0

one thing you could try would be to make SimpleParser a trait. This has usually worked better for me when using Specs2. Then you could call parse(tweet). I would also suggest breaking up the tests a little.

class SimpleParserSpec extends Specification with SimpleParser { 
     val tweet = """{"id":1,"text":"foo"}"""
     SimpleParser should {
        "parse out the id" in {
              val parsedTweet = parse(tweet)
              parsedTweet.id === 1
         }
}

From here you could add in the other fields that you wanted to test.

EDIT: Looking back at what I wrote, I see I didn't completely answer what you were asking. you could put the === and then failure into cases like you already had, but within the framework of what I have.

redeagle47
  • 1,235
  • 1
  • 14
  • 23