14. Let’s test a repository
@Stateless @Local(UserRepository.class)
public class UserJPARepository implements UserRepository {
@PersistenceContext Injected by the container.
private EntityManager em; How do we get one in our
tests?
public User create(User user) {
em.persist(user);
How do we test this?
return user;
}
...
}
15. Did you say Mocks?
public class MockUserRepositoryTests {
…
@Before public void injectDependencies() {
// Mock
em = mock(EntityManager.class);
userRepository = new UserJPARepository(em);
}
@Test public void testCreateUser() throws Exception {
// Setup
User user = createTestUser();
// Execute
User createdUser = userRepository.create(user);
// Verify
verify(em, times(1)).persist(user);
assertThat(createdUser, equalTo(user));
…
18. Using a real EntityManager
public class RealUserRepositoryTests {
static EntityManagerFactory emf;
EntityManager em;
UserRepository userRepository;
@BeforeClass public static void beforeClass() {
emf = Persistence.createEntityManagerFactory("jpa-examples");
}
@Before public void setup() throws Exception {
// Initialize a real EntityManager
em = emf.createEntityManager();
userRepository = new UserJPARepository(em);
em.getTransaction().begin();
}
…
19. Testing with a real EntityManager
@Test
public void testCreateUser() throws Exception {
// Setup
User user = createTestUser();
// Execute
User createdUser = userRepository.create(user);
em.flush();
em.clear();
// Verify
User foundUser = em.find(User.class, createdUser.getUserId());
assertThat(foundUser, equalTo(createdUser));
}
20. Better, but …
• Requires a separate persistence.xml
• Manual transaction management
• Flushes and clears the persistence context
manually
21. Bringing the test as close as possible to production
ARQUILLIAN ENTERS THE SCENE
22. We must walk before we run
@RunWith(Arquillian.class) // #1 Use the Arquillian test
public class GreeterTest { runner.
@Deployment // #2
public static JavaArchive createDeployment() { Assemble a micro-
return ShrinkWrap.create(JavaArchive.class) deployment
.addClass(Greeter.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
A CDI Bean.
@Inject // #3 Managed by the container.
Greeter greeter;
Injected by Arquillian.
@Test // #4
public void should_create_greeting() {
assertEquals("Hello, Earthling!", Test like you normally do.
greeter.greet("Earthling")); No mocks.
} Just the real thing.
}
24. @Deployment
• Assemble test archives with ShrinkWrap
• Bundles the -
– Class/component to test
– Supporting classes
– Configuration and resource files
– Dependent libraries
25. Revisiting the deployment
@Deployment // #1
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class) // #2
.addClass(Greeter.class) // #3
.addAsManifestResource(EmptyAsset.INSTANCE,
"beans.xml"); // #4
}
1. Annotate the method with @Deployment
2. Create a new JavaArchive. This will eventually create a JAR.
3. Add our Class-Under-Test to the archive.
4. Add an empty file named beans.xml to enable CDI.
26. Test enrichment
• Arquillian can enrich test class instances with
dependencies.
• Supports:
– @EJB
– @Inject
– @Resource
– @PersistenceContext
– @PersistenceUnit
– @ArquillianResource
– …
27. Revisiting dependency injection
@Inject
Greeter greeter;
• The CDI BeanManager is used to create a
new bean instance.
• Arquillian injects the bean into the test
class instance, before running any tests.
28. Writing your tests
• Write assertions as you normally would
– No record-replay-verify model
– Assert as you typically do
– Use real objects in your assertions
29. Running your tests
• Run the tests from your IDE or from your
CI server
– Just like you would run unit tests
• Run as JUnit test - Alt+Shift+X, T
• Run as Maven goal - Alt+Shift+X, M