NullPointerException in FunSuiteLike

20 views
Skip to first unread message

Dominik Haneberg

unread,
Sep 20, 2015, 1:05:49 PM9/20/15
to scalatest-users
Hi!

I encountered a problem when creating tests with FunSuiteLike. I reduced the code to a minimal instance that exhibits the problem. 3 classes are needed:

COSISuite.scala

package kiv.tests.experiments

import org.scalatest.Suite

abstract class COSISuite extends Suite {

 
def constructTestcases() {
    println
("constructTestcases")
    testcasesForProofs
()
 
}

 
def testcasesForProofs()

  constructTestcases
()
}


COSIPerSpecSuite.scala

package kiv.tests.experiments

class COSIPerSpecSuite extends COSISuite with TestsForSteps {
 
override def testcasesForProofs() {
   
(1 to 2) foreach ((i:Int) => {
      println
("testcasesForProofs: " + i)
      createTests
(i)
   
})
 
}
}


TestsForSteps.scala

package kiv.tests.experiments

import org.scalatest.FunSuiteLike

trait
TestsForSteps extends FunSuiteLike {
  println
("Init TestsForSteps")
 
def createTests(i:Int)  = {
   
println("createTests: " + i)
    test
("Test " + i){ assert(1 == 1) }
 
}
}

Calling "new COSIPerSpecSuite" to create the test suite results in a java.lang.NullPointerException at org.scalatest.FunSuiteLike$class.test(FunSuiteLike.scala:112). After some headaches I realized that it's not my code giving null values to method test(.). So the problem is somewhere in the inner workings of trait FunSuiteLike. I looked into the code of scalatest and think that the call to "engine.registerTest(testName, Transformer(testFun _), ..." is the problem and that engine is not initialized when the test case creation happens. With this assumption I tried to change the initialization order to circumvent the problem. And in fact creating an instance of COSIPerSpecSuite works without problems when I change COSISuite from "extends Suite" to "extends Suite with FunSuiteLike". But this feels like an ugly hack. Is there a proper solution to ensure that trait FunSuiteLike is properly initialized before the first call to test(.) happens and still follow the advice in the documentation to FunSuite to "register tests during object construction"?

Thanks,
Dominik

Bill Venners

unread,
Sep 20, 2015, 5:45:17 PM9/20/15
to scalate...@googlegroups.com
Hi Dominik,

The way you mix these together, the order of initialization will cause
COSISuite to be initialized first. It calls testcasesForProofs in
COSIPerSpecSuite, which calls createTests in TestsForSteps, which
calls test in FunSpecLike. But FunSpecLike hasn't been initialized yet
because that will be initialized after COSISuite. One way you could
fix that is make COSISuite a trait, then mix TestForSteps in *before*
COSISuite in COSIPerSpecSuite, like this:

import org.scalatest.Suite

trait COSISuite extends Suite {

def constructTestcases() {
println("constructTestcases")
testcasesForProofs()
}

def testcasesForProofs()

constructTestcases()
}

import org.scalatest.FunSuiteLike

trait TestsForSteps extends FunSuiteLike {
println("Init TestsForSteps")
def createTests(i:Int) = {
println("createTests: " + i)
test("Test " + i){ assert(1 == 1) }
}
}

class COSIPerSpecSuite extends TestsForSteps with COSISuite {
override def testcasesForProofs() {
(1 to 2) foreach ((i:Int) => {
println("testcasesForProofs: " + i)
createTests(i)
})
}
}

Paste that into the REPL and you'll get:

scala> new COSIPerSpecSuite
Init TestsForSteps
constructTestcases
testcasesForProofs: 1
createTests: 1
testcasesForProofs: 2
createTests: 2
import org.scalatest.Suite
defined trait COSISuite
import org.scalatest.FunSuiteLike
defined trait TestsForSteps
defined class COSIPerSpecSuite
res2: COSIPerSpecSuite = COSIPerSpecSuite@ce99a05

Bill
> --
> You received this message because you are subscribed to the Google
> Groups "scalatest-users" group.
> To post to this group, send email to scalate...@googlegroups.com
> To unsubscribe from this group, send email to
> scalatest-use...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/scalatest-users?hl=en
> ScalaTest itself, and documentation, is available here:
> http://www.artima.com/scalatest
> ---
> You received this message because you are subscribed to the Google Groups
> "scalatest-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to scalatest-use...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Bill Venners
Artima, Inc.
http://www.artima.com

Dominik Haneberg

unread,
Sep 21, 2015, 3:49:58 PM9/21/15
to scalatest-users
Hi, Bill!
Thanks for your help.
Reply all
Reply to author
Forward
0 new messages