Question

I am doing a web application with Scala and Akka actors and I'm having some troubles with the tests.

In my case I need to taste an actor who talks with the Database. To do the unit testing I would like to use a Fake Database but I can't replace the new with my desired fake object.

Let's see some code:

Class MyActor extends Actor {
    val database = new Database()

    def receive = { ... }
}

And in the tests I would like to inject a FakeDatabase object instead Database. I've been looking in Internet but the best that I found is:

  • Add a parameter to the constructor.
  • Convert the val database to a var so in the test I could access the attribute by the underlying and replace it.

Both solutions solve the problem but are very dirty.

Isn't a better way to solve the problem?

Thanks!

Was it helpful?

Solution

The two primary options for this scenario are:

  1. Dependency Injection Use a DI framework to inject a real or mock service as needed. In Akka: http://letitcrash.com/post/55958814293/akka-dependency-injection

  2. Cake Pattern This is a Scala-specific way of achieving something akin to dependency injection without actually relying on injection. See: Akka and cake pattern

OTHER TIPS

Echoing the advice here, I wouldn't call injecting the database in the constructor dirty. It might have plenty of benefits, including decoupling actor behaviour from the particular database instance.

However if you know there is only ONE database you will be always using in your production code, then think about defining a package level accessible constructor and a companion object returning a Props object without parameters by default.

Example below:

object MyActor {

    def props() : Props = Props(new MyActor(new Database()))

}

class MyActor private[package](database : IDatabase) extends Actor {

    def receive = { ... }
}

In this case you will still be able to inject the test database in your tests case (given the same package structure), but prevent users of your code from instantiating MyActor with unexpected database instance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top