scalaunit-testingmockingmockitoscala-dispatch

How to mock Dispatch http client in Scala test?


I've got some code dealing with HTTP requests and I want to unit-test it.
Thus I'm trying to mock dispatch.Http or even better dispatch.HttpExecutor (0.8.5) with Scala (2.9.1.final), Mockito (1.9.0-rc1) and ScalaTest (1.6.1) but even can't make my test code compilable.
Here in MyHttpTest I want to receive certain HTTP response for any HTTP request:

import org.scalatest.FunSuite
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito.when
import org.mockito.Matchers.any
import dispatch._

class MyHttpTest extends FunSuite with MockitoSugar {
  test("example") {
    val httpMock = mock[HttpExecutor]
    when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_HTTP_response")
  }
}

But it produces compilation error:

error: overloaded method value thenReturn with alternatives:
(httpMock.HttpPackage[String],<repeated...>[httpMock.HttpPackage[String]])org.mockito.stubbing.OngoingStubbing[httpMock.HttpPackage[String]] <and>
(httpMock.HttpPackage[String])org.mockito.stubbing.OngoingStubbing[httpMock.HttpPackage[String]]
cannot be applied to (java.lang.String)
when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_response")

So how to mock dispatch client?


Solution

  • I was going to answer this with a suggestion that you should try ScalaMock instead of Mockito, because I wrongly assumed that the problem you were having was caused by Mockito not really understanding Scala (whereas ScalaMock has been created in Scala from the ground up). However:

    1. That's not your problem, and
    2. It turns out that ScalaMock fails when trying to mock HttpExecutor because it doesn't know how to handle a type defined in a package object (ExceptionListener). Damn! I'll fix it ASAP - thanks for bringing it to my attention.

    Anyway, you can't create an instance of HttpExecutor#HttpPackage because it's an abstract type. So to get around it, you need to extend HttpExecutor and make HttpPackage concrete. For example:

    class MyHttpTest extends FunSuite with MockitoSugar {
      trait TestHttpExecutor extends HttpExecutor {
        type HttpPackage[T] = T
      }
      test("example") {
        val httpMock = mock[TestHttpExecutor]
        when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_HTTP_response")
      }
    }