Arquillian : An introduction

4,092 views

Published on

Testing with real objects

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,092
On SlideShare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
124
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Arquillian : An introduction

  1. 1. Arquillian : An introduction Testing with real objects Vineet Reynolds March 2012
  2. 2. How does this solve our problems?WHY ARQUILLIAN?
  3. 3. Test Doubles reduxHow did we arrive at the currenttesting landscape?
  4. 4. 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; } ...}
  5. 5. 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)); …
  6. 6. Seems perfect, but…verify(em, times(1)).persist(user);• Is brittle• Violates DRY• Is not a good use of a Mock
  7. 7. Implementations matterTESTING WITH REAL OBJECTS
  8. 8. Using a real EntityManagerpublic 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(); } …
  9. 9. Testing with a real EntityManager@Testpublic 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));}
  10. 10. Better, but …• Requires a separate persistence.xml• Manual transaction management• Flushes and clears the persistence context manually
  11. 11. Bringing the test as close as possible to productionARQUILLIAN ENTERS THE SCENE
  12. 12. We must walk before we run@RunWith(Arquillian.class) // #1 Use the Arquillian testpublic 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.}
  13. 13. @RunWith(Arquillian.class) JUnit TestNG >= 4.8.1 > 5.12.1
  14. 14. @Deployment• Assemble test archives with ShrinkWrap• Bundles the - – Class/component to test – Supporting classes – Configuration and resource files – Dependent libraries
  15. 15. 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 @Deployment2. 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.
  16. 16. Test enrichment• Arquillian can enrich test class instances with dependencies.• Supports: – @EJB – @Inject – @Resource – @PersistenceContext – @PersistenceUnit – @ArquillianResource – …
  17. 17. Revisiting dependency injection@InjectGreeter 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.
  18. 18. 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
  19. 19. 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
  20. 20. Let’s recap@RunWith(Arquillian.class) // #1 Use the Arquillian testpublic 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.}
  21. 21. Using Arquillian to test the repositoryTESTING THE REPOSITORY - DEMO
  22. 22. The stuff that Arquillian does under the hoodWHAT DID YOU JUST SEE?
  23. 23. Arquillian changes the way you see testsWHY SHOULD YOU USE IT?
  24. 24. Refining the tests involving a databaseTHE PERSISTENCE EXTENSION
  25. 25. ATDD/BDD with ArquillianTHE DRONE AND JBEHAVEEXTENSIONS

×