Reputation: 9521
I have the following trait:
trait TraitToTest{
def doSome(): Unit
}
and some implementations
class Impl1 extends TraitToTest
class Impl2 extends TraitToTest
class Impl3 extends TraitToTest
//...
I have some general contracts for TraitToTest
each implementation has to adhere to. I can describe the contract as follows:
class TraitTest extends FunSpec with Matchers{
describe("TraitTest general contracts"){
it("should test contract 1"){
val impl = //some impl of TraitToTest
//the test
}
}
}
The problem is I don't want to duplicate the TraitToTest
general contracts for each implementation of TraitToTest
. I just want to supply the implementation instance as a sort of factory or so...
Is it possible to do in Scalatest
?
Upvotes: 0
Views: 277
Reputation: 1828
Another way to do it is to generate appropriate tests.
class TraitToTest extends FunSpec {
val testCases =
List(
("Impl1", new Impl1()),
("Impl2", new Impl2()),
("Impl3", new Impl3())
)
testCases.foreach {
case (name, impl) =>
describe(name) {
it("should fulfill contract 1") {
// tests for impl go here
}
}
}
Output of sbt test
:
[info] Impl1
[info] - should fulfill contract 1
[info] Impl2
[info] - should fulfill contract 1
[info] Impl3
[info] - should fulfill contract 1
I'm not sure if this is a known pattern, but personally I use this to write most of my tests - find the contract I want to test and create test cases for various sets of inputs and expected outputs.
Upvotes: 3
Reputation: 3964
Transform TraitTest
into an abstract class:
abstract class TraitTest extends FunSpec with Matchers {
val impl: TraitToTest
describe("TraitTest general contracts"){
it("should test contract 1"){
impl.doSome()
}
}
}
The implementation suites will instantiate the respective trait:
class Impl1TestSuite extends TraitTest {
override val impl = new Impl1()
}
Upvotes: 2