scalaplayframeworkmockitoscala-catsmockito-scala

Mocking a Service that returns Cats EitherT with Guice and MockitoSugar


I am trying to write some functional tests, and I want to mock a service that consumes an external provider. But I can not set up the mock for the functions that return EitherT

This is the Trait whose implementation call the external service

@ImplementedBy(classOf[ExternalServiceImpl])
trait ExternalService {
  def index: EitherT[Future, String, JsValue]
}

In the CustomAppPerSuite trait I set up

val mockExternalService = mock[ExternalService]

 implicit override lazy val app = new GuiceApplicationBuilder()
.in(Mode.Test)
.overrides(bind[ExternalService].toInstance(mockExternalService))
.build()

val externalService = app.injector.instanceOf[ExternalService]

Then When I try to mock the succesful response

  "ExternalController#index" should {

    "return index data" in {
      doReturn(EitherT.rightT(Json.parse("""{"key": "value"}""")).when(externalService).index
      val fakeRequest = FakeRequest(GET, "/api/external")
      val result = externalController.index().apply(fakeRequest)
      status(result) mustBe OK
    }

But I get this error

[error]  found   : cats.data.EitherT[cats.package.Id,Nothing,JsValue]
[error]  required: cats.data.EitherT[scala.concurrent.Future,String,JsValue]
[error]   def index = EitherT.rightT(

I only want to mock the successful response, because it is what I am testing. Is there a way to do this?


Solution

  • Try helping the compiler out by providing some type parameters to rightT like so

    EitherT.rightT[Future, String](Json.parse("""{"key": "value"}"""))
    

    instead of

    EitherT.rightT(Json.parse("""{"key": "value"}"""))