Is there a way to combine beforeEach with "should behave like" ?

137 views
Skip to first unread message

Jacob Eckel

unread,
Aug 24, 2015, 8:05:21 AM8/24/15
to scalatest-users
I have a set of tests all of which require same code before and after each test, for this purpose I happily use BeforeAndAfterEach.
Now I need to perform the same set of tests several times with different settings (which I can store in a shared object). For this purpose I would use test sharing with "should behave like".
However, I don't see a way to combine "should behave like" with BeforeAndAfterEach. I am looking for something like this:

"Something" should behave like setOfTests(new Settings1)
"Something" should behave like setOfTests(new Settings2)

trait MyBehaviors { this: FlatSpec =>
  def setOfTests(s: Settings) {
    it should "do something" in {
      assert(...)
    }

    it should "return something" in {
      assert(...)
    }
  }

 def beforeEach() {
    // some code that should be performed before each test in the set, where do I put it????
  }
}

Any advice?

Bill Venners

unread,
Aug 24, 2015, 8:11:46 AM8/24/15
to scalate...@googlegroups.com
Hi Jacob,

I'd put the beforeEach in the FlatSpec itself, the one you mix the
trait MyBehaviors into. Something like:

trait MySpec extends FlatSpec with BeforeAndAfterEach with MyBehaviors {

def beforeEach() {
// some code that should be performed before each test in the set,
so I put it here
}

"Something" should behave like setOfTests(new Settings1)
"Something" should behave like setOfTests(new Settings2)
}

If you want to use MyBehaviors in more than one Suite class, you can
pull out the beforeEach method into a trait itself that you mix into
all Suite classes that need it.

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

Jacob Eckel

unread,
Aug 24, 2015, 8:23:13 AM8/24/15
to scalatest-users
Hi Bill, thank you for your quick answer.
I will follow your advice, however my beforeEach code depends on the settings passed into setOfTests and it is not clear how to pull the corresponding settings object while in beforeEach.
Is there a good design for that?

Jacob Eckel

unread,
Aug 27, 2015, 2:53:51 AM8/27/15
to scalatest-users
For the time the only reasonable solution I have found is to encode the settings into Tags within setOfTests, then I am able to pull the tags and reconstruct the settings in beforeEach corresponding to the BeforeAndAfterEachTestData trait.
It would be great if there was a way to register complete objects (and not only Strings) with each test and so the objects would be available in beforeEach.

Bill Venners

unread,
Aug 27, 2015, 8:10:23 AM8/27/15
to scalate...@googlegroups.com
Hi Jacob,

Can you post some code of what you ended up with? There is probably a
better way, but I can't quite follow how the settings is involved.

Thanks.

Bill

Jacob Eckel

unread,
Aug 27, 2015, 8:52:20 AM8/27/15
to scalatest-users
Currently I use the Tag-based method below.
It would be great if I could pass a Settings object directly to the testSet() or to "should behave like" and it would be directly retrievable from within beforeEach().

class TestSpec() extends FlatSpecLike with Matchers with BeforeAndAfterEachTestData {

// have to invent a tag with a name for each object of Settings
val TagNamePrefix = "MySettingsTag"
case object NormalTag extends Tag(TagNamePrefix+"Normal")
case object SpecialTag extends Tag(TagNamePrefix+"Special")
// and put them into a map by name
var settingsMap: String => Settings = Map (
NormalTag.name -> Settings(0, 0, someGlobalNormalObject),
SpecialTag.name -> Settings(10, 10, someGlobalSpecialObject)
)

override def beforeEach(testData: TestData) {
val s: Settings = retrieveSettings(testData)
// some code depending on settings before each test
super.beforeEach(testData)
}

/** the ugly way to retrieve settings in beforeEach */
private def retrieveSettings(testData: TestData): Settings = {
val tags = testData.tags.filter(_.startsWith(TagNamePrefix))
assert(tags.size == 1)
settingsMap(tags.last)
}

"A thing" should behave like testSet(NormalTag)
"A thing with special settings" should behave like testSet(SpecialTag)

def testSet(t: Tag) {
it should "test something" taggedAs t in {
// ...
}

it should "test something else" taggedAs t in {
// ...
}
}
}
Reply all
Reply to author
Forward
0 new messages