Some Name
Some Name

Reputation: 9521

Implementing factory in Scalatest

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

Answers (2)

Astrid
Astrid

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

Antot
Antot

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

Related Questions