Mock Scala.js classes

419 views Asked by At

I'm trying to test React component written in Scala.js, which fetches list of categories from the server. I was able to provide alternative jQuery instance to the component, but jQuery mock itself cannot be compiled. Here is mock's code:

import org.scalajs.jquery.{JQueryXHR, JQueryStatic}

import scala.scalajs.js
import utest._

class jQueryMock extends JQueryStatic {

  var awaitedRequests = Map.empty[String, PartialFunction[js.Any, js.Any]]

  def whenGet(url: String)(response: PartialFunction[js.Any, js.Any]): Unit = {
    awaitedRequests += (url -> response)
  }

  override def get(url: String, data: js.Any, success: js.Any, dataType: js.Any): JQueryXHR = {
    awaitedRequests.get(url) match {
      case Some(response) =>
        if(response.isDefinedAt(data))
          success.asInstanceOf[(js.Any) => Unit](response(data))
        else
          assert(false)
      case None => assert(false)
    }
    new JQueryXHR {}
  }
}

There are two problems in this code according to Scala.js compiler:

  • Warning:(14, 95) Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0.

    override def get(url: String, data: js.Any, success: js.Any, dataType: js.Any): JQueryXHR = {

  • Error:(19, 9) Traits, classes and objects extending js.Any may not have inner traits, classes or objects

    new JQueryXHR {}

Is there any other way to mock any native class in Scala.js (or in fact any other way to test backend queries)?

Edit

If I throw out extends JQueryStatic and new JQueryXHR {} and change return type of def get, the class compiles fine. This way I could write jQuery wrapper handling AJAX stuff, which I will be able to mock. This will work, but seems to be an awful lot of trouble. Is there any other way to do this?

1

There are 1 answers

0
Bartek Andrzejczak On BEST ANSWER

I've created tests using my facade and it's mock:

Facade

class Http {
  def get(url: String)(success: (js.UndefOr[js.Any]) => Unit): Unit =
    jQuery.getJSON(url, js.undefined, success)
}

Mock

class HttpMock extends Http {

  var awaitedRequests = Map.empty[String, js.Any]

  def whenGet(url: String, response: js.Any): Unit = {
    awaitedRequests += (url -> response)
  }

  def verifyNoOutstandingRequests() =
    assert(awaitedRequests.isEmpty)

  override def get(url: String)(success: (js.UndefOr[js.Any]) => Unit): Unit = {
    awaitedRequests.get(url) match {
      case Some(response) =>
          success(response)
          awaitedRequests -= url
      case None => assert(false)
    }
  }
}