When do before() and after() get invoked within a ScalaTest class with BeforeAndAfter trait - scala

Consider the following minimal viable self contained testcase for BeforeAndAfter and BeforeAndAfterAll:
import org.scalatest.{BeforeAndAfter, BeforeAndAfterAll, FunSuite}
class BeforeAndAfterTestTest extends FunSuite with BeforeAndAfter with BeforeAndAfterAll {
override protected def beforeAll(): Unit = println("beforeAll")
override protected def afterAll(): Unit = println("afterAll")
override protected def before(fun: => Any)(implicit pos: Position): Unit = {
println("before")
}
override protected def after(fun: => Any)(implicit pos: Position): Unit = {
println("after")
}
test("hello1") { println("hello1") }
test("hello2") { println("hello2") }
}
The result of running this through scalatest is:
So :
The before/afterAll do execute
The before/after do not
What is needed to have the before and after methods get invoked?

You are supposed to call before and after, not override them:
import org.scalatest.{BeforeAndAfter, BeforeAndAfterAll, FunSuite}
class BeforeAndAfterTestTest extends FunSuite with BeforeAndAfter with BeforeAndAfterAll {
override protected def beforeAll(): Unit = println("beforeAll")
override protected def afterAll(): Unit = println("afterAll")
before {
println("before")
}
after {
println("after")
}
test("hello1") { println("hello1") }
test("hello2") { println("hello2") }
}
See the documentation here
If you want overrideable methods, you should use BeforeAndAfterEach, not BeforeAndAfter (doc)

Related

How to override an implicit value, that is imported?

I have tried solutions, described in How to override an implicit value?, but it does not help. Here is a code example.
A definition of TestImplicit abstraction with 2 different implementations (analogue of ExecutionContextExecutor):
trait TestImplicit {
def f(s:String):Unit
}
object TestImplicitImpl1 extends TestImplicit {
override def f(s: String): Unit = println(s"1: $s")
}
object TestImplicitImpl2 extends TestImplicit {
override def f(s: String): Unit = println(s"2: $s")
}
And in the ImplDefinition object a q variable is defined to be used implicitly via import (analogue of ExecutionContext.Implicits.global):
object ImplDefinition {
implicit val q:TestImplicit = TestImplicitImpl1
}
Client that defines a method, accepting TestImplicit implicitly (analogue of scala.concurrent.Future):
trait TestImplicitClient {
def fu(implicit ti:TestImplicit):Unit
}
object TestImplicitClient extends TestImplicitClient {
override def fu(implicit ti: TestImplicit): Unit = {
println("client")
ti.f("param")
}
}
The next step, a client of client, that chooses which implementation of TestImplicit should be used, the decision is done via import (analogue of API that uses Future):
object ClientOfClient {
import somepackage.ImplDefinition.q
def t():Unit =
TestImplicitClient.fu
}
Now in test, I want to use this ClientOfClient.t(), but I need to override implicit, and use TestImplicitImpl2 instead. The main idea behind - implicits should be defined/overridable by the client of API, but not by API itself:
import somepackage.{ClientOfClient, TestImplicit, TestImplicitImpl2}
import org.junit.Test
class ImplTest {
// trying to hide it via import, does not help
import somepackage.ImplDefinition.{q => _,_}
#Test def test(): Unit ={
//trying to hide it via downgrading to non-implicit, does not work either
val q = somepackage.ImplDefinition.q
implicit val ti = TestImplicitImpl2
ClientOfClient.t()
}
}
Each time I run test, I get in the output:
client
1: param
But not expected:
client
2: param
How can I fix it? I need a way to allow clients to override implicits and stay with as simple API as possible. Which means, I do not want to add additional implicit parameter into ClientOfClient.t() method.
As soon as you have a singleton object ClientOfClient with a hard-coded constant TestImplicitImpl1 everywhere, there is essentially nothing you can do. But there are several work-arounds.
1. Use default implicit parameters
object ClientOfClient {
def t()(implicit ti: TestImplicit = ImplDefinition.q): Unit =
TestImplicitClient.fu
}
object ImplTest {
def test(): Unit = {
implicit val ti2 = TestImplicitImpl2
ClientOfClient.t()
}
}
ImplTest.test() // 2: param
2. Supply the implicit through a separate method that can be overridden
If you want to make the implicit overridable, then make ClientOfClient extendable, and create a method (here "cocti") that returns the implicit, instead of importing the implicit directly. You can then override the method (whereas you cannot override an import).
This here produces 2: param in the end of the day:
trait TestImplicit {
def f(s: String): Unit
}
object TestImplicitImpl1 extends TestImplicit {
override def f(s: String): Unit = println(s"1: $s")
}
object TestImplicitImpl2 extends TestImplicit {
override def f(s: String): Unit = println(s"2: $s")
}
object ImplDefinition {
implicit val q: TestImplicit = TestImplicitImpl1
}
trait TestImplicitClient {
def fu(implicit ti: TestImplicit): Unit
}
object TestImplicitClient extends TestImplicitClient {
override def fu(implicit ti: TestImplicit): Unit = {
println("client")
ti.f("param")
}
}
class ClientOfClient {
implicit def cocti: TestImplicit = {
ImplDefinition.q
}
def t():Unit =
TestImplicitClient.fu
}
object ImplTest {
def test(): Unit = {
implicit val ti2 = TestImplicitImpl2
new ClientOfClient {
override def cocti = ti2
}.t()
}
}
ImplTest.test() // 2: param

How to stack behaviour with traits extending BeforeAfterAll

I'm in a situtation where I have 2 traits extending BeforeAfterAll doing different actions for integration tests: One managing the database and the other the file system. For example:
trait DBSpecification extends BeforeAfterAll {
override def beforeAll() = {
println("DB -> BeforeAll")
}
override def afterAll() = {
println("DB -> AfterAll")
}
}
trait FileSystemSpecification extends BeforeAfterAll {
override def beforeAll() = {
println("FileSystem -> BeforeAll")
}
override def afterAll() = {
println("FileSystem -> AfterAll")
}
}
class MyTest extends Specification with DBSpecification with FileSystemSpecification {
"some test" in {
1 ==== 1
}
}
If I do like this, only the prints of the last trait are executed, in this case FileSystemSpecification. If I try calling super from the traits, I start having some compilation problems. I've tried already a bunch of ways, but couldn't figure out the solution.
ScalaTest has some examples on its documentation, but couldn't find a way with Specs2.
Any ideas?
Yes traits are not the best thing for composing behaviour. Here is the boilerplaty way to do it:
import org.specs2.mutable._
import org.specs2.specification._
trait DBSpecification extends BeforeAfterAll {
def beforeAll() = {
println("DB -> BeforeAll")
}
def afterAll() = {
println("DB -> AfterAll")
}
}
trait FileSystemSpecification extends BeforeAfterAll {
def beforeAll() = {
println("FileSystem -> BeforeAll")
}
def afterAll() = {
println("FileSystem -> AfterAll")
}
}
trait FileSystemDBSpecification extends DBSpecification with FileSystemSpecification {
override def beforeAll() = {
super[DBSpecification].beforeAll()
super[FileSystemSpecification].beforeAll()
}
override def afterAll() = {
super[DBSpecification].afterAll()
super[FileSystemSpecification].afterAll()
}
}
class MyTestSpec extends Specification with FileSystemDBSpecification {
"some test" in {
1 ==== 1
}
}

Scala: Not able to find implicit from object

I have the following scala code. I don't understand why the implicit is not being figured by the compiler. I also tried putting the import line inside Main. Note however that when the implicit object was created inside Main, then the code ran correctly
import LoggingAddon._
object Main {
def main(args: Array[String]): Unit = {
val dog = new Dog
Util.act(dog)
}
}
class Dog {
def bark(): Unit = {
println("woof")
}
}
trait Action[A] {
def action(x: A): Unit
}
trait WithoutLogging[A] extends Action[A] {
}
trait WithLogging[A] extends Action[A] {
}
object LoggingAddon {
implicit object DogWithLogging extends WithLogging[Dog] {
override def action(x: Dog): Unit = {
println("before")
x.bark()
print("after")
}
}
}
object NoLoggingAddion {
implicit object DogWithoutLogging extends WithoutLogging[Dog] {
override def action(x: Dog): Unit = {
x.bark()
}
}
}
object Util {
def act(x: Dog)(implicit nolog: Action[Dog]): Unit = {
nolog.action(x)
}
}
I have imported the necessary implicit from the LoggingAddon but still the scala compiler says could not find implicit Action[Dog]
All I'm trying to do is make a pluggable typeclass. Rather than changing any piece of code, merely change the import statements to have different side effects
Simply move the order of usage where implicit is imported, I moved to the bottom in following example
class Dog {
def bark(): Unit = {
println("woof")
}
}
trait Action[A] {
def action(x: A): Unit
}
trait WithoutLogging[A] extends Action[A] {
}
trait WithLogging[A] extends Action[A] {
}
object LoggingAddon {
implicit object DogWithLogging extends WithLogging[Dog] {
override def action(x: Dog): Unit = {
println("before")
x.bark()
print("after")
}
}
}
object NoLoggingAddion {
implicit object DogWithoutLogging extends WithoutLogging[Dog] {
override def action(x: Dog): Unit = {
x.bark()
}
}
}
object Util {
def act(x: Dog)(implicit nolog: Action[Dog]): Unit = {
nolog.action(x)
}
}
import LoggingAddon._
object Main {
def main(args: Array[String]): Unit = {
val dog = new Dog
Util.act(dog)
}
}

How to mock an interface in Guice module with ScalaMock?

How can I simply mock an interface needed for injection in Guice using ScalaMock?
I've ended up using
import org.scalamock.MockFactoryBase
import org.scalatest.exceptions.TestFailedException
trait MyMockFactory extends MockFactoryBase {
type ExpectationException = TestFailedException
override protected def newExpectationException(message: String, methodName: Option[Symbol]): TestFailedException = ???
}
and in TestModule
class TestModule extends AbstractModule with MyMockFactory {
override def configure(): Unit = {
val mockObject = mock[ClassName]
bind(classOf[ClassName]).toInstance(mockObject)
}
}
Use a separate test module by binding mocked instances to class names and use that module to inject objects for your tests.
Test Module goes like this:
class TestModule extends AbstractModule {
override def configure(): Unit = {
val mockObject = mock[ClassName]
bind(classOf[ClassName]).toInstance(mockObject)
}
}
Spec goes like this:
class SomeSpec extends FlatSpec {
val injector = Guice.createInjector(new TestModule)
val mockObject = injector.getInstance(classOf[ClassName])
}

How to inject services into actors using the Play 2.4?

I am able to inject services into my Application class with no issues. But somehow I am unable to inject into the actors themselves.
My actor:
class PollerCrow #Inject()(
#Named("pollService") pollService: PollService[List[ChannelSftp#LsEntry]]
, #Named("redisStatusService") redisStatusService: StatusService
, #Named("dynamoDBStatusService") dynamoDbStatusService: StatusService
) extends BaseCrow {
... impl and stuff ...
}
My actor's companion object:
object PollerCrow extends NamedActor {
override def name: String = this.getClass.getSimpleName
val filesToProcess = ConfigFactory.load().getString("poller.crow.files.to.process")
def props = Props[PollerCrow]
}
I'm getting the following when I run it:
IllegalArgumentException: no matching constructor found on class watcher.crows.PollerCrow for arguments []
How can I fix this?
Edit:
I have binded my actors:
class ActorModule extends AbstractModule with AkkaGuiceSupport {
override def configure() {
bindPollerActors()
}
private def PollActors() = {
bindActor[PollerCrow](PollerCrow.name)
}
}
Edit 2:
Additional details to the class:
abstract class BaseCrow extends Crow with Actor with ActorLogging
class PollerCrow #Inject()(
#Named(ServiceNames.PollService) pollService: PollService[List[ChannelSftp#LsEntry]]
, #Named(ServiceNames.RedisStatusService) redisStatusService: StatusService
, #Named(ServiceNames.DynamoDbStatusService) dynamoDbStatusService: StatusService
) extends BaseCrow {
override def receive: Receive = {
...
}
}
object PollerCrow extends NamedActor {
override def name: String = this.getClass.getSimpleName
def props = Props[PollerCrow]
}
trait NamedActor {
def name: String
final def uniqueGeneratedName: String = name + Random.nextInt(10000)
}
You might to make Guice aware of you actors. This is clean approach:
import com.google.inject.AbstractModule
import play.api.libs.concurrent.AkkaGuiceSupport
class ActorModule extends AbstractModule with AkkaGuiceSupport {
override def configure(): Unit = {
bindActor[YourActor]("your-actor")
}
}
#Singleton
class YourActor #Inject()(yourService: IYourService) extends Actor {
override def receive: Receive = {
case msg => unhandled(msg)
}
}
And application.conf:
play.modules {
enabled += "ActorModule"
}
For those who don't want to hassle, just call injector directly and don't forget to import Application to scope:
Play.application.injector.instanceOf[YourService]
Play.application.injector.instanceOf(BindingKey(classOf[YourService]).qualifiedWith("your-name"));