Trait

org.scalatest.fixture

NoArg

Related Doc: package fixture

Permalink

trait NoArg extends DelayedInit with () ⇒ Unit

A function that takes no parameters (i.e., a Function0 or "no-arg" function) and results in Unit, which when invoked executes the body of the constructor of the class into which this trait is mixed.

This trait extends DelayedInit and defines a delayedInit method that saves the body of the constructor (passed to delayedInit) for later execution when apply is invoked.

This trait is somewhat magical and therefore may be challenging for your collegues to understand, so please use it as a last resort only when the simpler options described in the "shared fixtures" section of your chosen style trait won't do the job. NoArg is intended to address a specific use case that will likely be rare, and is unlikely to be useful outside of its intended use case, but it is quite handy for its intended use case (described in the next paragraph). One potential gotcha, for example, is that a subclass's constructor body could in theory be executed multiple times by simply invoking apply multiple times. In the intended use case for this trait, however, the body will be executed only once.

The intended use case for this method is (relatively rare) situations in which you want to extend a different instance of the same class for each test, with the body of the test inheriting the members of that class, and with code executed before and/or after the body of the test.

For example, Akka's TestKit class takes an ActorSystem, which must have a unique name. To run a suite of tests in parallel, each test must get its own ActorSystem, to ensure the tests run in isolation. At the end of each test, the ActorSystem must be shutdown. With NoArg, you can achieve this by first defining a class that extends TestKit and mixes in NoArg. Here's an example taken with permission from the book Akka Concurrency, by Derek Wyatt:

import akka.actor.ActorSystem
import akka.testkit.{TestKit, ImplicitSender}
import java.util.concurrent.atomic.AtomicInteger
import org.scalatest.fixture.NoArg

object ActorSys {
  val uniqueId = new AtomicInteger(0)
}

class ActorSys(name: String) extends
        TestKit(ActorSystem(name))
        with ImplicitSender
        with NoArg {

  def this() = this(
    "TestSystem%05d".format(
       ActorSys.uniqueId.getAndIncrement()))

  def shutdown(): Unit = system.shutdown()

  override def apply() {
    try super.apply()
    finally shutdown()
  }
}

Given this implementation of ActorSys, which will invoke shutdown after the constructor code is executed, you can run each test in a suite in a subclass of TestKit, giving each test's TestKit an ActorSystem with a unique name, allowing you to safely run those tests in parallel. Here's an example from Akka Concurrency:

class MyActorSpec extends fixture.WordSpec
        with Matchers
        with UnitFixture
        with ParallelTestExecution {

  def makeActor(): ActorRef =
    system.actorOf(Props[MyActor], "MyActor")

  "My Actor" should {
    "throw when made with the wrong name" in new ActorSys {
      an [Exception] should be thrownBy {
        // use a generated name
        val a = system.actorOf(Props[MyActor])
      }
    }
    "construct without exception" in new ActorSys {
      val a = makeActor()
      // The throw will cause the test to fail
    }
    "respond with a Pong to a Ping" in new ActorSys {
      val a = makeActor()
      a ! Ping
      expectMsg(Pong)
    }
  }
}

UnitFixture is used in this example, because in this case, the fixture.WordSpec feature enabling tests to be defined as functions from fixture objects of type FixtureParam to Unit is not being used. Rather, only the secondary feature that enables tests to be defined as functions from no parameters to Unit is being used. This secondary feature is described in the second-to-last paragraph on the main Scaladoc documentation of fixture.WordSpec, which says:

If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, ... In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

Since FixtureParam is unused in this use case, it could be anything. Making it Unit will hopefully help readers more easily recognize that it is not being used.

Note: As of Scala 2.11, DelayedInit (which is used by NoArg) has been deprecated, to indicate it is buggy and should be avoided if possible. Those in charge of the Scala compiler and standard library have promised that DelayedInit will not be removed from Scala unless an alternate way to achieve the same goal is provided. Thus it should be safe to use NoArg, but if you'd rather not you can achieve the same effect with a bit more boilerplate by extending (() => Unit) instead of NoArg and placing your code in an explicit body method. Here's an example:

import akka.actor.ActorSystem
import akka.testkit.{TestKit, ImplicitSender}
import java.util.concurrent.atomic.AtomicInteger
import org.scalatest.fixture.NoArg

object ActorSys {
  val uniqueId = new AtomicInteger(0)
}

class ActorSys(name: String) extends
        TestKit(ActorSystem(name))
        with ImplicitSender
        with (() => Unit) {

  def this() = this(
    "TestSystem%05d".format(
       ActorSys.uniqueId.getAndIncrement()))

  def shutdown(): Unit = system.shutdown()
  def body(): Unit

  override def apply() = {
    try body()
    finally shutdown()
  }
}

Using this version of ActorSys will require an explicit body method in the tests:

class MyActorSpec extends fixture.WordSpec
        with Matchers
        with UnitFixture
        with ParallelTestExecution {

  def makeActor(): ActorRef =
    system.actorOf(Props[MyActor], "MyActor")

  "My Actor" should {
    "throw when made with the wrong name" in new ActorSys {
      def body() =
        an [Exception] should be thrownBy {
          // use a generated name
          val a = system.actorOf(Props[MyActor])
        }
    }
    "construct without exception" in new ActorSys {
      def body() = {
        val a = makeActor()
        // The throw will cause the test to fail
      }
    }
    "respond with a Pong to a Ping" in new ActorSys {
      def body() = {
        val a = makeActor()
        a ! Ping
        expectMsg(Pong)
      }
    }
  }
}

Source
NoArg.scala
Linear Supertypes
() ⇒ Unit, DelayedInit, AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. NoArg
  2. Function0
  3. DelayedInit
  4. AnyRef
  5. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Value Members

  1. final def !=(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  4. def apply(): Unit

    Permalink

    Executes the body of the constructor that was passed to delayedInit.

    Executes the body of the constructor that was passed to delayedInit.

    Definition Classes
    NoArg → Function0
  5. final def asInstanceOf[T0]: T0

    Permalink
    Definition Classes
    Any
  6. def clone(): AnyRef

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  7. final def delayedInit(body: ⇒ Unit): Unit

    Permalink

    Saves the body of the constructor, passed as body, for later execution by apply.

    Saves the body of the constructor, passed as body, for later execution by apply.

    Definition Classes
    NoArg → DelayedInit
  8. final def eq(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  9. def equals(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  10. def finalize(): Unit

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  11. final def getClass(): Class[_]

    Permalink
    Definition Classes
    AnyRef → Any
  12. def hashCode(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  13. final def isInstanceOf[T0]: Boolean

    Permalink
    Definition Classes
    Any
  14. final def ne(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  15. final def notify(): Unit

    Permalink
    Definition Classes
    AnyRef
  16. final def notifyAll(): Unit

    Permalink
    Definition Classes
    AnyRef
  17. final val styleName: Int

    Permalink

    This method exists to cause a compile-time type error if someone accidentally tries to mix this trait into a Suite.

    This method exists to cause a compile-time type error if someone accidentally tries to mix this trait into a Suite.

    This trait is intended to be mixed into classes that are constructed within the body (or as the body) of tests, not mixed into Suites themselves. For an example, the the main Scaladoc comment for this trait.

  18. final def synchronized[T0](arg0: ⇒ T0): T0

    Permalink
    Definition Classes
    AnyRef
  19. def toString(): String

    Permalink
    Definition Classes
    Function0 → AnyRef → Any
  20. final def wait(): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  21. final def wait(arg0: Long, arg1: Int): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  22. final def wait(arg0: Long): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )

Inherited from () ⇒ Unit

Inherited from DelayedInit

Inherited from AnyRef

Inherited from Any

Ungrouped