Mittwoch, 30. September 2009

JUnit 4.7 Rule for cleanup EasyMock object after test

I try the JUnit 4.7 rule feature and I wrote a super small ExternalResource class for easymock cleanup (reset) here is the example code that makes mocking setup easier:

import static org.easymock.EasyMock.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.rules.ExternalResource;

/**
* Mock resource class for cleanup mock objects after each test run.
*/
public class MockResource extends ExternalResource {

private List mockObjects = new ArrayList();

public   T createMockObject(Class clazz) {
T mock = createMock(clazz);
mockObjects.add(mock);
return mock;
}

protected void after() {
for (Object mock : mockObjects)
reset(mock);
} 
} 


/**
* Example test which use the rule for cleanup the mocks.
*/
public class ObserverTest {

@Rule
public MockResource mockResources = new MockResource();

Observer mockObserver = mockResources.createMockObject(Observer.class);

@Test
public void testObserver() throws Exception {
Car subject = new Car();
subject.register(mockObserver);
mockObserver.refresh(subject);
replay(mockObserver);
subject.setName("Porsche");
verify(mockObserver);
}
} 
With the mock resource rule no tearDown Method will be need the reset is be done by the rule.
Come to think of it, there will be sure more mocking work which can be done by a JUnit rule. So I think the rule feature is very nice and makes JUnit tests better to read ...

Montag, 28. September 2009

JPA with Hibernate Criteria API

I didn't know that with JPA Vendor Hibernate, the Criteria API of Hibernate can be used. That can be done by getting the Hibernate Session from the JPA Entity Manager.

Here a example code:

Session session = (Session) entityManager.getDelegate();
Criteria hibernateCriteria = session.createCriteria(Position.class);
// List with all positions
List list = hibernateCriteria.list();

Ok the question is would you like to have a dependency to Hibernate in your source code when you would use JPA, I think you wold not like to have, but technical it works...

Nicer would be a Criteria API that depends only on JPA and is not JPA vendor specific. For JPA 1 I didn't know a project that provides such a Criteria API that works fine, but in JPA 2 I think the Crititeria API would be part of the standard, so I think thats a good news.

Another example:

// Implementation with Hibernate Criteria
public List getPositionList() {
Session session = (Session) entityManager.getDelegate();
Criteria hibernateCriteria = session.createCriteria(Position.class);
hibernateCriteria.addOrder(Order.desc("createTime"));
return hibernateCriteria.list();
}

// Implementation with plain JPA
public List getPositionList() {
Query query = entityManager.createQuery("SELECT p FROM Position p ORDER BY p.createTime DESC");
return query.getResultList();
}