Arquillian : An introduction      Testing with real objects          Vineet Reynolds            March 2012
How does this solve our problems?WHY ARQUILLIAN?
Test Doubles reduxHow did we arrive at the currenttesting landscape?
Let’s test a repository@Stateless @Local(UserRepository.class)public class UserJPARepository implements UserRepository {  ...
Did you say Mocks?public class MockUserRepositoryTests {    …    @Before public void injectDependencies() {        // Mock...
Seems perfect, but…verify(em, times(1)).persist(user);• Is brittle• Violates DRY• Is not a good use of a Mock
Implementations matterTESTING WITH REAL OBJECTS
Using a real EntityManagerpublic class RealUserRepositoryTests {   static EntityManagerFactory emf;   EntityManager em;   ...
Testing with a real EntityManager@Testpublic void testCreateUser() throws Exception {    // Setup    User user = createTes...
Better, but …• Requires a separate persistence.xml• Manual transaction management• Flushes and clears the persistence cont...
Bringing the test as close as possible to productionARQUILLIAN ENTERS THE SCENE
We must walk before we run@RunWith(Arquillian.class)           // #1                                Use the Arquillian tes...
@RunWith(Arquillian.class)   JUnit           TestNG   >= 4.8.1         > 5.12.1
@Deployment• Assemble test archives with ShrinkWrap• Bundles the -  – Class/component to test  – Supporting classes  – Con...
Revisiting the deployment      @Deployment                                                   // #1      public static Java...
Test enrichment• Arquillian can enrich test class instances with  dependencies.• Supports:   –   @EJB   –   @Inject   –   ...
Revisiting dependency injection@InjectGreeter greeter;• The CDI BeanManager is used to create a  new bean instance.• Arqui...
Writing your tests• Write assertions as you normally would  – No record-replay-verify model  – Assert as you typically do ...
Running your tests• Run the tests from your IDE or from your  CI server  – Just like you would run unit tests     • Run as...
Let’s recap@RunWith(Arquillian.class)           // #1                                Use the Arquillian testpublic class G...
Using Arquillian to test the repositoryTESTING THE REPOSITORY - DEMO
The stuff that Arquillian does under the hoodWHAT DID YOU JUST SEE?
Arquillian changes the way you see testsWHY SHOULD YOU USE IT?
Refining the tests involving a databaseTHE PERSISTENCE EXTENSION
ATDD/BDD with ArquillianTHE DRONE AND JBEHAVEEXTENSIONS
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Arquillian : An introduction
Próxima SlideShare
Cargando en…5
×

Arquillian : An introduction

4.103 visualizaciones

Publicado el

Testing with real objects

Publicado en: Tecnología, Educación
  • Sé el primero en comentar

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

×