We have test fixtures using loan pattern. Leveraging this pattern to create "seed data" needed for a test to run. when test is dependent on data For e.g. following
"save definition" should {
"create a new record" in withSubject { implicit subject =>
withDataSource { implicit datasource =>
withFormType { implicit formtype =>
val definitn = DefinitionModel(-1, datasource.id, formtype.id, subject.role.id, Some(properties))
}
}
}
Where withSubject
, withDataSource
, withFormType
are test fixtures returning subject
, dataSource
, formType
data respectively from database. withDataSource
fixture requires subject
implicitly. Building DefinitionModel
requires datasource.id
and formtype.id
. so depending on the data requirement of a test calling such data builder fixtures is creating a lot of nested fixture situation. Is there a better way to "compose" /structure such fixtures?
The answer given by @Nader Hadji Ghanbari still holds. I would just like to add that since version 3.x.x of scalatest the traits changed names. Copying from the migration guide:
Mixin traits that override withFixture
4) In 3.0.0, the withFixture method has been moved from Suite to a new trait, TestSuite. This was done to make room for a withFixture method with a different signature in AsyncTestSuite. If you factored out a withFixture method into a separate "suite mixin" trait, you'll need to change "Suite" to "TestSuite" and "SuiteMixin" to "TestSuiteMixin". For example, given this trait from 2.2.6:
trait YourMixinTrait extends SuiteMixin { this: Suite => abstract override def withFixture(test: NoArgTest): Outcome = { // ... } }
You will need to add the "Test" prefix, like this:
trait YourMixinTrait extends TestSuiteMixin { this: TestSuite => abstract override def withFixture(test: NoArgTest): Outcome = { // ... } }
trait
is your friend. Composition is one of the requirements trait
s cover very nicely.
From Scala Test Docs
Composing fixtures by stacking traits
In larger projects, teams often end up with several different fixtures that test classes need in different combinations, and possibly initialized (and cleaned up) in different orders. A good way to accomplish this in ScalaTest is to factor the individual fixtures into traits that can be composed using the stackable trait pattern. This can be done, for example, by placing withFixture methods in several traits, each of which call super.withFixture.
For instance you can define the following trait
s
trait Subject extends SuiteMixin { this: Suite =>
val subject = "Some Subject"
abstract override def withFixture(test: NoArgTest) = {
try super.withFixture(test) // To be stackable, must call super.withFixture
// finally clear the context if necessary, clear buffers, close resources, etc.
}
}
trait FormData extends SuiteMixin { this: Suite =>
val formData = ...
abstract override def withFixture(test: NoArgTest) = {
try super.withFixture(test) // To be stackable, must call super.withFixture
// finally clear the context if necessary, clear buffers, close resources, etc.
}
}
Then you can bring this trait
s to your test context by just mixing them in:
class ExampleSpec extends FlatSpec with FormData with Subject {
"save definition" should {
"create a new record" in {
// use subject and formData here in the test logic
}
}
}
For more info on Stackable Traits Pattern you can refer to this article
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With