Discussions

News: Unitils 1.1 adds support for JPA

  1. Unitils 1.1 adds support for JPA (5 messages)

    Unitils helps you in writing simple and maintainable unit and integration tests with JUnit or TestNG. It glues together popular test libraries like DbUnit and EasyMock and offers integration with Spring and Hibernate. Unitils encourages applying good practices and testing guidelines. The ideas behind it are based on the authors' concrete experience on enterprise projects. In the 1.1 release, support has been added for writing tests for code that makes use of the Java Persistence API (JPA), in a very similar way as already available for Hibernate. In what follows, we'll demonstrate these features using a simple example. Code example Suppose we have a PersonRepository interface with an implementation based on JPA. The PersonRepository interface has a method findByLastName and is implemented as follows: public class PersonRepositoryImpl implements PersonRepository {

    @PersistenceContext
    private EntityManager entityManager;

    public List findByLastName(String lastName) {
    List persons = entityManager.createQuery("find person from Person person where person.lastName = :lastName").getResultList();
    return persons;
    }
    }
    We've written following test for this method: @JpaEntityManagerFactory(persistenceUnit = "test", configFile = "META-INF/persistence-test.xml")
    @Transactional(TransactionMode.COMMIT)
    @DataSet
    public class PersonRepositoryImplTest extends UnitilsJUnit4 {

    @PersistenceContext
    EntityManager entityManager;

    PersonRepository personRepository = new PersonRepositoryImpl();

    @Before
    public void init() {
    JpaUnitils.injectJpaResourcesInto(personRepository);
    }

    @Test
    public void testSearchByLastName() {
    List result = personRepository.findByLastName("Doe"));
    ReflectionAssert.assertPropertyLenEquals("firstName", Arrays.asList("John", "Jane"), result);
    }
    }
    You'll notice that this test extends UnitilsJUnit4. This makes sure that while running the test, unitils can hook into the execution of the test and inspect the test for annotations that ask for extra behavior to be performed. For JUnit version 3.x and TestNG, we offer similar base classes called UnitilsJUnit3 and UnitilsTestNG.
    JPA configuration The @JpaEntityManagerFactory annotation tells where to find the JPA persistence config file that needs to be loaded and the name of the persistence unit to load. If hibernate is configured as the persistence provider, the persistence config file could look as follows: 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_1_0.xsd"
    version="1.0">


    org.hibernate.ejb.HibernatePersistence






    You don't need to configure the DataSource in the test persistence config file. Under the hoods, care is taken that the JPA persistence context connects with the test database configured in unitils. Unitils offers a simple way to separate shared project and local configuration: common configuration is stored in a file unitils.properties located in the classpath, and developer specific configuration in a local file preferably stored in the user home dir. This enables every developer to configure make sure he uses his own database (schema). We advise to provide a test database (or schema) for each developer, which avoids conflicts and enables each database to evolve on its own pace. This is not the only possible way of configuring an EntityManagerFactory: If you're using Spring, you can make use of an EntityManagerFactory configured in a spring config file in your tests. For more information on this subject, check the documentation.
    Other features of unitils Unitils offers even a lot more: By annotating tests with @Transactional, every test is configured to run in a transaction which can be committed or rolled back at the end. A powerful system is also offered to automatically maintain every developer's test database. The reflection assert utility enables checking if the resulting object matches the expected one by scanning the complete object graph using reflection, with the ability of ignoring fields that are null in the expected object, ignoring the type and order of collections and the specific value of dates. In unitils 1.1, the reflection assert utility has been improved to make sure it gives a detailed, user friendly overview of all the differences between the expected and actual object. If you want to learn more about unitils, check out the tutorial and cookbook. If you have any comments, tips or questions, don't hesitate to post them on the user forum.

    Threaded Messages (5)

  2. Looks very interesting[ Go to top ]

    Definitely a technology I will be checking out. Sounds great. I am sure you will pick up flak from the TDD fanatics for supporting tests that are not real unit tests. :) Having said this I do have a small gripe. Your assertion for equals via reflection is very poorly chosen. assertRefEquals read (to me anyways) as assertReferenceEquals. I guess it is a 5 minute confusion thing anyways.
  3. If you use named query annotations, and put queries at the top of each entity class then they're automatically syntax checked when the persistence context is loaded. You can also fairly easily test the JPA layer with the Spring Abstract DI test class -- just make sure you've structured the Spring XML files such that the DAO layer can be booted up cleanly.
  4. If you use named query annotations, and put queries at the top of each entity class then they're automatically syntax checked when the persistence context is loaded.
    You can, but this is only syntax checking; it is useful to also have functional tests for your data access layer. Besides, I prefer to simply have my queries on the DAO/Repository, where they belong, instead of polluting my entities with them.
    You can also fairly easily test the JPA layer with the Spring Abstract DI test class -- just make sure you've structured the Spring XML files such that the DAO layer can be booted up cleanly.
    Unitils also supports working with a spring configured EntityManagerFactory, but indead you can also simply use spring's testing framework. The reason for still choosing unitils could then be for it's dbunit integration and automatic database maintenance features. Later this year we'll provide integration between spring's testing framework and unitils, so that you can make use of unitils' extra features in tests written with spring's framework.
  5. If you use named query annotations, and put queries at the top of each entity class then they're automatically syntax checked when the persistence context is loaded.

    You can, but this is only syntax checking; it is useful to also have functional tests for your data access layer. Besides, I prefer to simply have my queries on the DAO/Repository, where they belong, instead of polluting my entities with them.

    I see the point you're making about putting queries in the a DAO class. I still prefer to put as many queries as possible as named queries in the actual entity, which seems to be the approach promoted by the JPA spec -- since there's an annotation for it! I'll check out DBUnit too, but previously I've run Dao tests by having 'unit' tests run against HSQL in-memory with auto-create of tables, and the full app start up against a proper db. Its a PITA to do with JPA, i.e. have unit tests use a different DB to the full running app, but with a bit of a hack, and subclassing of some Spring/JPA related classes you can do it.
  6. It works well[ Go to top ]

    I've been using Unitils with my projects and it works really well. I have tried in the past to use an HSQL embedded database but always ran into compatibility problems when any nonstandard sql was used. In typical J2EE apps an extremely large portion of the regression testing involves the database integration and Unitils helps you with this. Using Unitils running against a empty database populated with data created specifically to test your methods gives you a high level of confidence that you have a correctly running application. The automatic database xsd schema generation that integrates with dbunit makes it easier to test your DAO layer than writing your own SQL inserts for one-off tests, especially given that the DBMaintainer removes all the database constraints for you. The Spring support annotations are also far easier to understand and use than the standard Spring base classes for test cases.