flurdy
flurdy

Reputation: 3972

Mockito ignores my Specs2 sugared verify steps when traits are involved

Normally Specs2 sugared Mockito verifications are checked and fails the test when appropriate. However in some instances they are ignored.

Normally this test verification fails as expected as myApp called myService at least once.

import org.specs2.mock.Mockito._

class MySpec extends Specification with Mockito {
  "MyApp" should {
     "blow up" in WithApplication {
         val myService = mock[MyService]
         val myApp = new MyApp(myService)

         myApp.doSomething          

         there was no(myService).doSomethingElse
     }
  }
}

(Note WithApplication is a Play! Framework thing)

However as I have hamfisted Cake Pattern traits into my components my tests look like this.

class MySpec extends Specification with Mockito {
  "MyApp" should {
     "blow up" in WithApplication with MockRegistry {

         val myApp = new MyApp(myService)

         myApp.doSomething          

         there was no(myService).doSomethingElse
     }
  }
}

where MockRegistry looks something like this

trait MockRegistry extends Mockito with MyServiceComponent {
  val myService = mock[MyService]
}

My Cake patterned test does not fail verification, ever. I can change this to anything and they all get ignored.

there was no(myService).doSomethingElse
there was one(myService).doSomethingElse
there was two(myService).doSomethingElse

However by replacing the sugared mockito step with a direct call to the java methods it does fail when appropriate.

import org.mockito.Mockito._

verify(myService, times(1)).doSomethingElse

So it seems involving traits on the test method seems to have properly confused Mockito.

Upvotes: 0

Views: 676

Answers (2)

Eric
Eric

Reputation: 15557

That's because the Mockito extension of MockRegistry doesn't know that exceptions needs to be thrown in case of failure. But the Mockito on Specification does because Specification has the ThrownExpectations trait mixed-in.

So you can either removed the Mockito extension from MockRegistry or add ThrownExpectations to it:

trait MockRegistry extends MyServiceComponent {
  val myService = mock(classOf[MyService])
}

// or
import org.specs2.matcher.ThrownExpectations

trait MockRegistry extends MyServiceComponent with ThrownExpectations {
  val myService = mock(classOf[MyService])  
}  

Upvotes: 2

flurdy
flurdy

Reputation: 3972

And as expected it was due to the traits. It was in face due too many Mockito trait-ing...

My spec had a mockito trait. My cake pattern mocked component registry also had a mockito trait. On the test method they were both part of the object, which seems to confuse Specs2/Mockito.

So by removing Mockito sugar from my mock component registry:

//import org.specs2.mock.Mockito._
import org.mockito.Mockito._

trait MockRegistry extends MyServiceComponent {
  val myService = mock(classOf[MyService])
}

And only have the Mockito sugar in the Spec then my sugared verifications started to work as expected again.

Upvotes: 0

Related Questions