I’ve finally released version 1.0 of the grails build-test-data plugin.
If you’re not familiar with build-test-data, the quick summary is that it puts a
build() method on all grails domain objects. Calling that method will automatically construct and save an instance of that domain object that conforms to all of the domain’s constraints. It also allows you to override the values that you want to explicitly set. It makes your tests much cleaner and less fragile as you only need to specify the values that actually matter to a particular test method instead of building a huge graph of objects just to satisfy constraints.
The plugin has been quite stable for the past 6 months or so, and has survived upgrades from grails 1.0.X through grails 1.2.1 with minimal changes. Because of this, I’ve decided to move the version from 0.2.3 to 1.0 to indicate that the plugin is stable and ready to be used. I’ve also added the LICENSE file releasing the plugin under the Apache 2.0 open source license (the same license as grails). It was always open source, but I had neglected to add the official license file in the past.
If you’re not familiar with the build-test-data plugin, the documentation on the wiki is thorough, I’ve also given a presentation on build-test-data that explains why it’s better than other existing data generation technologies.
The biggest changes for this release compared to the last are a number of bugfixes around making sure that both sides of a one-to-many relationship get populated correctly and that there isn’t a need to
refresh() from the database.
Previously, if you had an Author that
hasMany Books, and each Book
belongsTo an Author, you’d need to
refresh the Author if you tried to build a new book with an existing author:
Author eap = Author.findByName("Edgar Allan Poe") Book b = Book.build(author: eap, title: "The Tell-Tale Heart") assertEquals eap.name, b.author.name // works, linked in OK previously assertEquals 1, eap.books.size() // FAILED previously WORKS now, previously the book wasn't added properly to the author side of things
The previous workaround was to call
eap.refresh() to reload the author from the database, or to have the user manually
addToBooks(b). Both solutions were ugly and kludgy and this issue has now been fixed.