scalascalatestimplicit

ScalaTest : inject implicit variable


I am from Java background and I am trying to write UnitTests using Scala.

My class is as follows :

import com.softwaremill.sttp.{HttpURLConnectionBackend, Uri, sttp}

class MyClient(endpoint: String, principal: String) {

  private implicit val serialization = org.json4s.native.Serialization
  private implicit val backend = HttpURLConnectionBackend()

  def getDataSet(id: String) : Option[DataSet] = {
      //sttp.get(url).send <-- will use 'bakend'
  }
}

here the implicit variable 'backend' is used to plugin the HTTP Client implementation.

In the UnitTest I am supposed to plugin the SttpBackendStub .

implicit val testingBackend = SttpBackendStub.synchronous
        .whenRequestMatches(_.uri.path.startsWith("/dataSet"))
        .thenRespond(dataSetJson)

val client = new MyClient("http://dummy", "dummy")

However when I initiate MyClient instance, it will still use HttpURLConnectionBackend instead of SttpBackendStub

Is there workaround to ingest 'testingBackend' into the MyClient during testing ?


Solution

  • The use of implicit here is making you think the problem is more complicated than it is. You're instantiating HttpURLConnectionBackend directly in MyClient so that's the "backend" you're going to get. If you want to use a different one, you'll have to pass it in to MyClient. You can give it a default value for production use but pass in a mock when you instantiate it in your test.

    class MyClient(endpoint: String, principal: String,
        implicit val backend: BackendInterface = HttpURLConnectionBackend) {
    
      private implicit val serialization = org.json4s.native.Serialization
    
      def getDataSet(id: String) : Option[DataSet] = {
          //sttp.get(url).send <-- will use 'bakend'
      }
    }
    

    And in your test:

    val testingBackend = SttpBackendStub.synchronous
            .whenRequestMatches(_.uri.path.startsWith("/dataSet"))
            .thenRespond(dataSetJson)
    
    val client = new MyClient("http://dummy", "dummy", testingBackend)