user2664655
user2664655

Reputation: 251

Mocking Play WSRequestHolder get method using Scalamock

I'm trying to test the following line of code using ScalaTest and ScalaMock.

val responseFuture = wsClient.url(url).withQueryString(params: _*).get()

wsClient type is THttpClient, which is a wrapper of play.api.libs.ws.WS.

Given that:

val mockHttpClient = mock[THttpClient]

is properly injected into my class under test, the test code is something like this:

val expectedUrl = "some url"
val mockRequestHolder = mock[WSRequestHolder]
inSequence {
  (mockHttpClient.url _).expects(expectedUrl).returns(mockRequestHolder)
  (mockRequestHolder.withQueryString _).expects(where {
    (parameters: Seq[(String, String)]) => {
      // assertions on parameters
      // ...
      true
    }
  }).returns(mockRequestHolder)

  val stubResponse = stub[WSResponse]
  val jsonBody = "{}"
  (stubResponse.json _).when().returns(Json.parse(jsonBody))
  (mockRequestHolder.get _).expects().returns(Future(stubResponse))
}

IntelliJ is highlighting mockRequestHolder.get as an error saying: cannot resolve symbol get. Nevertheless I'm able to run the test but the mock is clearly not working, and I'm getting: java.util.NoSuchElementException: JsError.get.

The mock is working when I try to mock any other method of WSRequestHolder, but not with method get.

Is this a ScalaMock bug or am I doing something wrong?

Upvotes: 0

Views: 985

Answers (2)

Markon
Markon

Reputation: 4600

I don't know if you have solved already the issue, but I have tried to do something similar recently and I kind of got it working with the following code:

val wsClientMock = mock[WSClient]
val wsRequestMock = mock[WSRequest]
val wsResponseMock = mock[WSResponse]
(wsRequestMock.withAuth _).expects(username, password, WSAuthScheme.BASIC).returning(wsRequestMock)
(wsRequestMock.get _).expects().returning(Future[WSResponse](wsResponseMock))
(wsClientMock.url _).expects(bootstrapUrl).returning(wsRequestMock)
(wsResponseMock.status _).expects().returning(200)

"kind of" because I need to mock also the response, otherwise I get results like

ERROR[default-akka.actor.default-dispatcher-4] OneForOneStrategy - Unexpected call: json()

due to the fact that the code calling the WSClient is calling the method .json of WSResponse.

Upvotes: 1

Matthias
Matthias

Reputation: 1

Sorry, I don't know Scala Mock but I suggest you to have a look at MockWS a library which comes with a mocked WS client: play-mockws

With MockWS you define a partial function which returns an Action for a Route. This enables you to precisely configure mocked answers and test your http client code.

Upvotes: 0

Related Questions