Testing Actors in Akka - scala

When i run base example for testing actors:
class MySpec(_system: ActorSystem) extends TestKit(_system) with ImplicitSender
with WordSpec with MustMatchers with BeforeAndAfterAll {
I got error:
class WordSpec needs to be a trait to be mixed in
what am I doing wrong?

In ScalaTest 2.0 you can find both class and trait for WordSpec. The class named WordSpec and trait is WordSpecLike. So just use WordSpecLike instead of WordSpec:
class MySpec(_system: ActorSystem) extends TestKit(_system) with ImplicitSender
with WordSpecLike with MustMatchers with BeforeAndAfterAll {

In addition to what 1esha proposed, there's one more solution in akka documentation
If for some reason it is a problem to inherit from TestKit due to it being a concrete class instead of a trait, there’s TestKitBase:
import akka.testkit.TestKitBase
class MyTest extends TestKitBase {
implicit lazy val system = ActorSystem()
// put your test code here ...
shutdown(system)
}
The implicit lazy val system must be declared exactly like that (you can of course pass arguments to the actor system factory as needed) because trait TestKitBase needs the system during its construction.

As of Scalatest 2.0, the Specs you mix in are now classes not traits. Which means you can't use them with Akka's test kit... both are classes and you can only extend one of them.
Switch to scalatest 1.9.1. It's still supported by them and is the last version that released before they made that change and broke things for akka users. In 1.9.1, the specs are still traits.

Related

ScalaTest: Is there a flaw defining Test Suites as object rather than class?

I have a very specific use-case and in order to reduce instantiation time for the test suites I define them as an object and not as a class e.g.
import org.scalatest._
import scala.collection.mutable.Stack
object StackSuite extends FunSuite with Matchers {
test("stackShouldPopValuesIinLastInFirstOutOrder") {
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
stack.pop() should equal(2)
stack.pop() should equal(1)
}
}
This works but is there a fundamental issue or flaw regarding doing this? separate from the multithreading issue should each test be executed separately and in the unfortunate case of having modifyable state at the suite level.
UPDATE: when I say "reduce instantiation time" I meant overall e.g. accounting for heavyweight fixture data inside the object/class and not simply the pure Suite class instantiation time. Since object is a singleton then it would be a lookup rather than an instantiation of a new class.
I need to do this in order to distribute millions of tests across a grid of computers. Some tests are standard scalatest others are evaluating the permutations of a set of input parameters therefore the need to reduce the startup time for the instantiation of the Suite.
btw I do this to execute each test in a cluster machine:
import scala.reflect.runtime.universe
// I receive the suite and test names as input
val suite = "com.mycomp.StackSuite"
val test = "stackShouldPopValuesIinLastInFirstOutOrder"
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val module = runtimeMirror.staticModule(suite)
val obj = runtimeMirror.reflectModule(module)
val status = obj.asInstanceOf[TestSuite].execute(test)
in order to reduce instantiation time for the test suites I define them as an object and not as a class
I had a quick look at org.scalatest.tools.Runner (and DiscoverySuite) implementation, and I don't think this can reduce the instantiation time.
Remember how objects are actually compiled on JVM: you have a class StackSuite$ which extends Suite and has a public parameterless constructor (because it has to be called from StackSuite's static initializer). It's found and handled precisely like a class StackSuite would be.
EDIT: if you find the suite and run it yourself in this way instead of using ScalaTest's own API, then yes, you'll get a lookup instead of instantiation. Assuming no concurrency issues, there should be no problem: execute itself is threadsafe.
If you do not feel the need to modularize your testing by using inheritance then there is no problem in using an Object instead of a class. Else classes can help you in segregating the different kinds of testing.
From the ScalaTest docs :
Instead of duplicating code by mixing the same traits together repeatedly, we recommend you create abstract base classes for your project that mix together the features you use the most. For example, you might create a UnitSpec class (not trait, for speedier compiles) for unit tests that looks like:
package com.mycompany.myproject
import org.scalatest._
abstract class UnitSpec extends FlatSpec with Matchers with
OptionValues with Inside with Inspectors
You can then write unit tests for your project using the custom base class, like this:
package com.mycompany.myproject
import org.scalatest._
class MySpec extends UnitSpec {
// Your tests here
}

Instantiating all classes that extend trait in Scala

So I'm building a library, and the problem I have is as follows:
I have a trait, such as
package my.library
trait Animal {
def randomFunctions
}
What I need to know is all the classes the consumer code has, that extend/implement said trait, such as
package code.consumer
case class Cat extends Animal
case class Dog extends Animal
So in summary: inside my library (which has the trait) I need to find out all classes (in consumer code) that extend/implement the trait.
I finally solved this by using reflections (https://github.com/ronmamo/reflections) with the following little snippet:
val reflection = new Reflections()
reflection.getSubTypesOf(classOf[Animal])
An option would be to use a sealed trait. This forces all implementations of the trait to reside in the same file as the trait was defined.
This would break your separation of consumer and library code but you would be sure to get all implementations.
The only other option I can think of is to use an IDE, like IntelliJ which has an option to find all implementation based on given trait.

What is the specific difference between a sealed trait and an abstract sealed class in scala?

I am looking to define the following algebraic data type in scala:
sealed trait Beat
case object Rest extends Beat
case object Hit extends Beat
Is there any difference, if I were to define this instead as:
abstract sealed class Beat
case object Rest extends Beat
case object Hit extends Beat
i.e. using an abstract sealed class instead of a trait? The definitions appear to be equivalent.
There is no difference in the meaning of sealed whether you put it on an (abstract) class or a trait. So in your case, the two examples are indeed (almost) equivalent.
A difference between an abstract class and a trait comes apparent when a subclass wants to inherit from another class: A class/trait can always only extend a single class, but multiple traits. For example:
class SomeClass
sealed trait Beat1
abstract sealed class Beat2
case object Rest1 extends SomeClass with Beat1 // ok
case object Rest2 extends SomeClass with Beat2 // compile error
Otherwise, an abstract class and a trait are pretty much equivalent. The biggest differences in practice probably only appear once you are concerned about binary compatibility (kind of out of scope for this answer).
To add to gzm0's answer, a further difference between an abstract sealed class and a trait is that an abstract sealed class, like any other class but unlike a trait, can have constructor parameters:
abstract sealed class Duck(sound: String)
case object RealDuck extends Duck("quack")
case object RubberDuck extends Duck("squeak")

Cake pattern w/ akka: Providing implicit actorSystem to several layers

I'm currently baking my first cake pattern, so please bear with me.
I took my working monolithic app and I cutted it into functional layers. The cut looks clean but resulted in two of the layers that depend on an implicit ActorSystem.
I tried to solve this dependency like this:
trait LayerA {
this: ActorSystemProvider =>
private implicit val implicitActorSystem = actorSystem
import implicitActorSystem.dispatcher // implicit execution ctx
...
}
... and similarly for LayerX
My assembly class looks like:
class Assembly extends LayerA with LayerB with LayerX with ActorSystemProvider
where ActorSystemProvider simply instantiates the actor system.
This does not work given that the ActorSystem does not exist when the dependencies are resolved and the val's are instantiated, resulting in a NPE. This also looks really ugly and I'm sure there has to be a nicer/easier way to deal with it.
How should I deal with shared implicit dependencies among layers when using the cake pattern, like ActorSystem in this case?
Thanks
Self types is not a requirement for building a caked architecture, actually i use self types only in cases when a trait is a component of a layer. So when i need to place some implicit into the scope (for example ActorRefFactory for Spray Client) i just mix a trait in :
trait ActorSystemProvider {
implicit def actorSystem: ActorSystem
}
And on the lowest layer (so called "end of the world") i have the following code structure:
trait ServiceStack
extends SomeModule
with SomeModule2
with SomeModule3
with ActorSystemProvider
object ServiceLauncher extends App with ServiceStack {
val actorSystem = ActorSystem("ServiceName")
}
It's an oversimplified example (if you want a great example of a real system build on top of a Cake Pattern then you should definitely take a look at the Precog system, example where different modules/layers connects), but not you can mix implicit ActorSystem when you need it.
If you can instantiate the vals lazily rather than eagerly, you can make the implicitActorSystem a lazy val instead of a val. So it only gets executed when it is accessed the first time. I think this should solve the problem of NPE.
(Another little known interesting fact posted by #ViktorKlang FYI: If the initialization of a lazy val throws an exception, it will attempt to reinitialize the val at next access.)
Another way would be to make each of your methods which need execution context accept an implicit executionContext like:
trait LayerA {
def getUser(id: Int)(implicit ec: ExecutionContext) = {
...
}
}

Alias library implicits in a package object

Say I have:
import org.scalatest.ShouldMatchers._;
This brings a few implicit conversions into scope.
How can I alias them in a package object so that I can bring the implicits into scope with:
import code.ThePackageObject._;
Apparently the ShouldMatchers object extends the ShouldMatchers trait (where the actual definition of the implicits are done). This is a common idiom that allows to simply mix the trait where you need it. So you can simply mix ShouldMatchers (the trait) in your package object:
package object ThePackageObject extends ShouldMatchers