FactoryPal: New Scala framework for creating objects as test data. Say no to Fixtures and Mocks.

posted in: Scala | 12

FactoryPal is a scala framework that lets you create objects as test data. All you have to do is define the templates for each of the classes that you want FactoryPal to create objects from. After that, FactoryPal takes care of the rest.

Have you ever heard of factory_girl a super cool Ruby framework? Well, FactoryPal is factory_girl for Scala. It is pretty similar in its use. The difference is that FactoryPal is 100% type safe, which all of us Scala people love.

Here is a link to Github for the anxious https://github.com/mgonto/factory_pal

How do we use this?

FactoryPal is a singleton object where you can register all of the templates. For example, you can define a template as follows:

In this example, we register a new template for class model. If we try to set a value for a property that Person doesn’t has, your project won’t compile. If you try to set a value to a property that isn’t the type of that property, the project won’t compile either. Pretty cool huh? This was possible thanks to Scala Macros and Dynamic, two features added in the latest Scala 2.10 RC release.

For the time being, there are 3 supported operations on a field template.

  • mapsTo: This sets a certain specific value to that property.
  • isRandom: This sets a random value based on the type of the field. I’ve created some implicit randomizers for common objects (String, Long, Int, Double, etc.) but you can create your own. This is pretty similar to Ordering[T] used in List.
  • isAnotherFactoryModel: You tell FactoryPal that this is an inner object that can be constructed with another template of FactoryPal. For the time being, there can only be one template for each class. I’m going to change this very soon.

After we created the template, we can instantiate objects of that template as follows:

The create method has another overload that lets you add some field overriders for certain test. For example you can do the following:

And that’s it. That’s all you need to know to use this.

How can I add this to my project?

This is an example configuration for Build.scala for your SBT project :). There’re only snapshots for now as Scala 2.10 is not yet final. Once it’s, I’m going to make a release.

Take a look at the dependency and the repository!

What does it use internally?

Internally, this framework uses Scala Macros, Dynamic and the new Reflection library provided by Scala 2.10.

Next Steps

The next things I want to do are:

  • Add the posibility to have multiple templates for one Class
  • Add template inheritance
  • Add helpers to use this with ScalaTest and Specs2. For the moment, you can create the templates in the before.

For more information or to take a look at the code go to Github

EDIT: This is already released for Scala 2.10.0 final, please check this link for more information on how to use the latest version or take a loot at GitHub’s README

 

Share!Share on FacebookTweet about this on TwitterShare on RedditShare on Google+Share on LinkedInBuffer this pageEmail this to someoneFlattr the author
  • Kv

    Hi, I still have no idea what is FactoryPal, in which scenario this can be use?

    • ndeverge

      While developing in order to get datasets, or even better for unit testing :-)

      • Martin Gontovnikas

        That is 100% right. The whole idea is to use this for Unit Testing. However, many people use this for Seed objects as well

  • Noel Yap

    It looks like the problem of having multiple templates can be solved easily by not using a singleton object for FactoryPal. Allow each test to create a new FactoryPal instance and each test can register its own templates. This will also eliminate the need for a shared FactoryPal fixture.

  • Erik van Oosten

    How would this compare with ScalaCheck?

    • Martin Gontovnikas

      Hey.

      There are a few differences with ScalaCheck.

      This has a singleton object that is the factory which is intended to be the one to be used in every test.

      With FactoryPal you don’t need to create the object yourself. Suppose you have one constructor with one argument and some fields that are mutable and can be set via setter. With FactoryPal you just state the properties and the creation is done for you. With ScalaCheck you’d need to call the constructor and each setter manually.

      You can have nested templates or generators. Suppose that you have a person class which has a car. You can just say the car peoperty is created via other template and that’s it. Quite easy.

      There are times that for a certain teat you need to override some fields. You can do that here. Suppose you want to test validation for invalid email. You just create a person from the default template and override the email, that way you have a valid oerson except for email.

      I think that the syntax and usage is clearer as well.

      And soon you’ll have template inheritance.

      What so you think about this? I hope to hear your comments. Thanksss

  • Jamil

    How does this compare to ScalaCheck ? To greate a person generator, I would go like: val personGenerator: Gen[Person] = for (name <- arbitrary[String] age <- arbitrary[Int]) yield new Person(name = name, age = age)

    • Martin Gontovnikas

      Hey.

      There are a few differences with ScalaCheck.

      This has a singleton object that is the factory which is intended to be the one to be used in every test.

      With FactoryPal you don’t need to create the object yourself. Suppose you have one constructor with one argument and some fields that are mutable and can be set via setter. With FactoryPal you just state the properties and the creation is done for you. With ScalaCheck you’d need to call the constructor and each setter manually.

      You can have nested templates or generators. Suppose that you have a person class which has a car. You can just say the car peoperty is created via other template and that’s it. Quite easy.

      There are times that for a certain teat you need to override some fields. You can do that here. Suppose you want to test validation for invalid email. You just create a person from the default template and override the email, that way you have a valid oerson except for email.

      I think that the syntax and usage is clearer as well.

      And soon you’ll have template inheritance.

      What so you think about this? I hope to hear your comments.

  • Dirk Louwers

    I wonder how this would save me from using mocks. I regularly mock traits that have IO dependent implementations and therefore return a vast array of values from the same input. That can make it quite cumbersome to write factories for them. How would you envision this using FactoryPal?

  • finestglasses j.

    l Recalling my brothers’ experience before, he was too shy to wear his thick glasses. But now because of FG mens glasses, he is no longer shy and yet it helps him to have a good self-esteem.