2012-04-23
2012-04-15
2012-04-14
Jerusalem - My Impressions (my photos)
Hi, I just uploaded the second batch of my pictures from Jerusalem - different pictures and in black and white. Please check them out!
2012-04-13
Jerusalem - the City (my pictures)
Hi, I just uploaded my pictures from Jerusalem. Please check them out!
2012-04-03
Scala + Guice + Gradle: Integration tests (Part 5)
Previously I showed you how to add to your Scala + Guice project JPA 2 implemented by EclipseLink. In this article I will show you how to integration test it using the specs library.
build.gradle
Below are the relevant part of your build.gradle file.test { exclude "**/*IT.class" } task integrationTest(type: Test, dependsOn: testClasses) { include "**/*IT.class" } check.dependsOn integrationTest dependencies { testCompile group: 'org.scala-tools.testing', name: 'specs_2.9.1', version: '1.6.9' testCompile group: 'junit', name: 'junit', version: '4.+' }(This obviously is not the complete file.)
We specified a new task called integrationTest which will run our integration tests. It will run during gradle build as well. gradle test alone will NOT run them.
Step by step - PersistenceLibraryRepositorySpecIT.scala
package me.m1key.audioliciousmigration.repository import org.specs._ import org.specs.runner._ import org.junit.runner.RunWith import me.m1key.audioliciousmigration.persistence.JpaPersistenceProvider import me.m1key.audiolicious.domain.entities.Library import java.util.Date @RunWith(classOf[JUnitSuiteRunner]) class PersistenceLibraryRepositorySpecIT extends Specification with JUnit { val jpaPersistenceProvider = new JpaPersistenceProvider jpaPersistenceProvider.initialise val repository = new PersistenceLibraryRepository(jpaPersistenceProvider) val entityManager = jpaPersistenceProvider.getEntityManager //...This is the test declaration. It allows us to run the test as a JUnit test from the IDE. Notice that file name ends with ...IT.scala. This is how we differentiate integration tests.
Step by step - before
// ... doBeforeSpec { deleteLibraries } //...This will run before the test (just once).
Step by step - test
"Fetching latest library with no libraries" should { var library: Library = null doFirst { println("Preparing test 1...") deleteLibraries println("Test prepared. Libraries: %d".format(librariesCount)) } "return None." in { entityManager.getTransaction().begin() repository.getLatestLibrary() mustBe None entityManager.getTransaction().commit() } doLast { println("Cleaning up...") deleteLibraries println("Cleaned up. Libraries: %d".format(librariesCount)) } }This is a test. Notice the BDD style. The assertion is this line: repository.getLatestLibrary() mustBe None. doFirst and doLast allow us to prepare the test and clean up.
Step by step - another test
"Fetching library by UUID with three libraries" should { setSequential() var olderLibrary: Library = null var anotherOlderLibrary: Library = null var newerLibrary: Library = null doFirst { println("Preparing test 3...") deleteLibraries olderLibrary = insertLibrary Thread.sleep(1000) anotherOlderLibrary = insertLibrary Thread.sleep(1000) newerLibrary = insertLibrary println("Test prepared. Libraries: %d".format(librariesCount)) } "return correct 1st library." in { entityManager.getTransaction().begin() val library = repository.getLibrary(olderLibrary.getUuid).get entityManager.getTransaction().commit() library mustBe olderLibrary } "return correct 2nd library." in { entityManager.getTransaction().begin() val library = repository.getLibrary(anotherOlderLibrary.getUuid).get entityManager.getTransaction().commit() library mustBe anotherOlderLibrary } "return correct 3rd library." in { entityManager.getTransaction().begin() val library = repository.getLibrary(newerLibrary.getUuid).get entityManager.getTransaction().commit() library mustBe newerLibrary } doLast { println("Cleaning up...") deleteLibraries println("Cleaned up. Libraries: %d".format(librariesCount)) } }setSequential allows us to keep variables (olderLibrary, anotherOlderLibrary, newerLibrary) in scope for all tests.
Step by step - final clean up
//... doAfterSpec { deleteLibraries } //...
You can see the whole source for this file here.
Final note
gradle build will NOT run tests that have already run since the last code change! If you want them to run again, use gradle clean build.Download source code
Source code for this article can be obtained via GitHub. Please see the README file for building and running.
Labels:
Gradle,
Guice,
JPA,
Programming,
Scala
Scala + Guice + Gradle: JPA 2 & EclipseLink (Part 4)
Previously I showed you how to create a Singleton in Guice powered Scala project. In this article I will show you how you can (JPA 2) EclipseLink support.
This sample app is a console app, so we have to handle entity management ourselves.
persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="audioliciousPu"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>me.m1key.audiolicious.domain.entities.Library</class> <class>me.m1key.audiolicious.domain.entities.Artist</class> <class>me.m1key.audiolicious.domain.entities.Album</class> <class>me.m1key.audiolicious.domain.entities.Song</class> <class>me.m1key.audiolicious.domain.entities.Stat</class> <class>me.m1key.audiolicious.domain.entities.Rating</class> <properties> <property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306/audiolicious_test" /> <property name="eclipselink.jdbc.user" value="root" /> <property name="eclipselink.jdbc.password" value="" /> <property name="eclipselink.target-database" value="MYSQL" /> <property name="eclipselink.logging.level" value="OFF" /> <property name="eclipselink.orm.throw.exceptions" value="true" /> </properties> </persistence-unit> </persistence>
EntityManager
package me.m1key.audioliciousmigration.persistence import javax.persistence.EntityManager import javax.persistence.EntityManagerFactory import javax.persistence.Persistence class JpaPersistenceProvider extends PersistenceProvider { private var factory: EntityManagerFactory = _ private var entityManager: EntityManager = _ @Override def initialise: Unit = { factory = Persistence.createEntityManagerFactory("audioliciousPu") entityManager = factory.createEntityManager(); } @Override def getEntityManager: EntityManager = { return entityManager } @Override def close: Unit = { entityManager.close(); factory.close(); } }
Usage
val persistenceProvider = injector.getInstance(classOf[PersistenceProvider]) persistenceProvider.initialise val entityManager = persistenceProvider.getEntityManager entityManager.getTransaction().begin() //... entityManager.getTransaction().commit() persistenceProvider.close
build.gradle
repositories { // ... mavenRepo name: "EclipseLink", url: "http://download.eclipse.org/rt/eclipselink/maven.repo/" } dependencies { compile group: 'me.m1key.audiolicious', name: 'audiolicious-domain-objects', version: '0.1.0-SNAPSHOT' compile group: 'org.eclipse.persistence', name: 'eclipselink', version: '2.3.0' compile group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.0.0' compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.18' // … }We needed to explicitly add EclipseLink specific repository.
Conclusion
I did not present any entities here because in my app they come from another Java powered project. In the next article I will show you how to integration test this code.Download source code
Source code for this article can be obtained via GitHub. Please see the README file for building and running.
Labels:
EclipseLink,
Gradle,
Guice,
JPA,
Programming,
Scala
2012-04-02
Scala + Guice + Gradle: Singleton (Part 3)
In the previous part of this tutorial I explained how to use Guice in your Gradle + Scala project.
In this short post I will build up on that and show you how to create a singleton scoped instance, as the default scope in Grails is new every time requested.
Singleton
This is the singleton to be class:class PersistenceLibraryRepository @Inject() (private val persistenceProvider: PersistenceProvider) extends LibraryRepository { // ... }Nothing special here!
As far as I know, you cannot use the @Singleton annotation, so this is how you make this class a singleton:
class AudioliciousMigrationModule extends AbstractModule { @Override protected def configure() { bind(classOf[LibraryRepository]) .to(classOf[PersistenceLibraryRepository]) .in(Scopes.SINGLETON) } }Voila!
In Part 4 I will show you how to connect to a MySQL database using JPA 2 implemented by EclipseLink.
Download source code
Source code for this article can be obtained via GitHub.2012-04-01
Scala + Guice + Gradle (Part 2)
In Part 1 of this tutorial I showed you how to create a Gradle based Scala project. Now I will show you how to use Guice.
Basic example
The abstraction that defines the contract:package me.m1key.audioliciousmigration trait AudioliciousImporter { def importLibrary(libraryUuid: String): Unit }The implementation:
package me.m1key.audioliciousmigration.importer import me.m1key.audioliciousmigration.AudioliciousImporter private[audioliciousmigration] class RelativeDataImporter extends AudioliciousImporter { def importLibrary(libraryUuid: String): Unit = { println("Importing library [%s]...".format(libraryUuid)); println("Library [%s] imported.".format(libraryUuid)); } }Note package level private access - the implementation is not visible from the outside.
Here we bind implementations to abstractions:
package me.m1key.audioliciousmigration import com.google.inject.AbstractModule import com.google.inject.Provides import me.m1key.audioliciousmigration.importer.RelativeDataImporter class AudioliciousMigrationModule extends AbstractModule { @Override protected def configure() { bind(classOf[AudioliciousImporter]).to(classOf[RelativeDataImporter]) } }Finally, the bootstrap:
package me.m1key.audioliciousmigration import com.google.inject.Guice object Launcher { def main(args: Array[String]): Unit = { println("Audiolicious Importer") val injector = Guice.createInjector(new AudioliciousMigrationModule) val importer = injector.getInstance(classOf[AudioliciousImporter]) importer.importLibrary("UUID") println("Bye.") } }If you're new to Guice and you're confused, you can read more about it here.
In Part 3 I will show you how to create a singleton.
Download source code
Source code for this article can be obtained via GitHub.
Subscribe to:
Posts (Atom)