Testing your DAO’s with Java Rory Preddy
Agenda What we encounter Testing with JDBC CDI 101 Testing with CDI DeltaSpike Summary
What we encounter Entities or SQL DAO layer Service Layer (CDI, ManagedBean or EJB) Web layer Arquillian for testing Service with EJB’s Selenium on Web Layer No DAO testing
Why Test DAO? Persistence frameworks (JPA, JDO, etc) help but… Frameworks can be misconfigured Frameworks can be asked to do the wrong thing Incorrect mappings Cascade actions can be hell Physical DB’s are rarely in a sober state
What we encounter Testing with JDBC CDI 101 Testing with CDI Summary DeltaSpike Summary
Basic testing principles Create multiple databases In memory for local Physical for DEV/UAT Ensure the state of the database prior to testing Test in small chunks of data Don’t try to load everything into the database for a single test
Test with JDBC (demo) Maven build Create DB with Derby Tools Insert Base data with DBUnit Create a Connection Test CRUD Clean database
What we encounter Testing with JDBC CDI 101 Testing with CDI Summary DeltaSpike Summary
Content & Dependency Injection Inversion Of Control" object creation No more hardcoded dependencies Customer cs = new VerySpecialCustomer(); Basically the old Factory Pattern Hollywood Principle: “Don't call us, we call you!” Macho Principle “Dude, gimme that bloody stuff!” In CDI 1.0, you must add a beans.xml file to your archive Since CDI 1.1, it’s activated by default: All classes having a “bean defining annotation” become a bean You can still use beans.xml file to activate CDI explicitly ordeactivate it
Content & Dependency Injection Can we used in Standard Edition, Servlet or EJB containers Adds the Web conversation context + to standard contexts (request, session, application…) To activate CDI Create a beans.xml file (can be empty) Add maven dependencies In CDI 1.0, you must add a beans.xml file to your archive Since CDI 1.1, it’s activated by default: All classes having a “bean defining annotation” become a bean You can still use beans.xml file to activate CDI explicitly ordeactivate it
CDI history & actual state Main milestone : December 2009 : CDI 1.0 June 2013 : CDI 1.1 April 2014 : CDI 1.2 Q1 2016 : CDI 2.0 due Implementations : JBoss Weld (RI) : WildFly, JBoss EAP, Glassfish, Weblogic Apache OpenWebBeans : TomEE, Websphere Check http://cdi-spec.org
Dependency Injection @Inject
Dependency Injection public class HelloService { public String hello() { return "Hello World!"; }
Dependency Injection in Constructor public class MyBean { private HelloService service; @Inject public MyBean(HelloService service) { this.service = service; } public void displayHello() { display( service.hello();
Dependency Injection in setter public class MyBean { private HelloService service; @Inject public void setService(HelloService service) { this.service = service; } public void displayHello() { display( service.hello();
Dependency Injection in field public class MyBean { @Inject HelloService service; public void displayHello() { display( service.hello(); }
Qualifiers public interface HelloService { public String hello(); } public class AfrikaansHelloService implements HelloService { public String hello() { return "Howzit!"; public class EnglishHelloService implements HelloService { return "Hello World!";
Qualifiers @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface Afrikaans {} public @interface English {}
Qualifiers (declaring) @Afrikaans public class AfrikaansHelloService implements HelloService { public String hello() { return "Howzit!";} } @English public class EnglistHelloService implements HelloService { return “Hello world!";}
Qualifiers (assigning) public class MyBean { @Inject @Afrikaans HelloService service; public void displayHello() { display( service.hello(); } @Inject @English HelloService service;
Qualifiers with members @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface Language { Languages value(); @Nonbinding String description() default ""; public enum Languages { Afrikaans, ENGLISH }
Qualifiers (declaring) @Language(Afrikaans) public class AfrikaansHelloService implements HelloService { public String hello() { return "Howzit!"; } @Language(ENGLISH) public class EnglishHelloService implements HelloService { return "Hello World!"; }!
Qualifiers (assigning) public class MyBean { @Inject @Language(ENGLISH) HelloService service; public void displayHello() { display( service.hello(); } @Inject @Language(Afrikaans) HelloService service;
Reserved Qualifiers (filter) @Any – all beans, unless they have @New @Default, @Named (Filter) @New – forces the container to return a new bean instance each time @New public class SomeBean {..} public class AnotherBean { @Inject SomeBean bean1; @Inject SomeBean bean2; @PostConstruct void init() { log.info(bean1 == bean2); // false } ambiguous dependencies
Producers @Produces public MyNonCDIClass myProducer() { return new MyNonCdiClass(); } ... @Inject MyNonCDIClass bean;
Injecting EntityManager @Produces @Produces @PersistenceContext(unitName="CustomerDatabase") @CustomerDatabase EntityManager customerDatabasePersistenceContext; @inject @Inject @CustomerDatabase EntityManager myEntityManager Close public void close(@Disposes EntityManager em) { if (em.isOpen()) { em.close(); }
What we encounter Testing with JDBC CDI 101 Testing with CDI Summary DeltaSpike Summary
CDI Frameworks FRAMEWORK Who owns it Spring EMC (VMWARE) Guice Google Weld Redhat OpenWebBeans Apache Extension Who owns it DeltaSpike Apache
DeltaSpike? Seam 2.2 targets JBoss AS 5 and 6 as well as JBoss Enterprise Application Platform 5 - Java EE 5 based architecture Seam 2.3 targets Java EE 6 capabilities such as JSF2 and JPA2 on the JBoss Enterprise Application Platform 6 - Seam 2.3 also supports RichFaces 4 which is also available for commercial support via Web Framework Kit. If you are looking for the long-term support with a service level agreement of Seam 2.2 and/or Seam 2.3 then please contact us at http://www.redhat.com/contact/sales.html Seam 2.3 is part of Web Framework Kit, included as part of the JBoss Enterprise Application Platform subscription . Seam 2.3 was released in September 2012. This is an update to the Seam 2 code base to make it compatible with Jave EE 6. It runs well on JBoss AS 7. Seam 3 Active development of Seam 3 has been halted by Red Hat. Many projects have moved over to Apache DeltaSpike ,
What is in DeltaSpike? JPA Test-Control Module Role Core missing CDI @Stereotypes Bean Validation Container Control CDI container booting and shutdown and associated context lifecycle management Data Declarative queries, reducing boilerplate JPA @Transactional context and scope JSF Type-safe view config, multi-window handling, new scopes (WindowScoped, ViewScope, ViewAccessScoped, GroupedConversationScoped) and integration with DeltaSpike “core” messages and exception handling Scheduler Security Servlet Test-Control CdiTestRunner
EntityManager without DeltaSpike (demo) EntityManager's life cycle depends on its type, which can be: Full blown Application server Container-managed transactional Container-managed extended Servlet and Standard Edition Application-managed With Application managed: Create Custom Weld Junit runner Boot a Transaction manager (Seam) or create a custom EntityManager scope: entityManager.getTransaction().begin() entityManager.getTransaction().commit(); entityManager.getTransaction().rollback(); Dispose of Entity manager
EntityManager with DeltaSpike (demo) Annotation DAO with @Transaction Paved the way for @Transactional in Java EE 7 Inject DeltaSpike Runner
What we encounter Testing with JDBC CDI 101 Testing with CDI Summary DeltaSpike Summary
Summary JDBC testing JPA testing Use DBUnit and Derby tools Inject entity manager Use DeltaSpike test Controls
Next month - DeltaSpike Data vs Spring Data Questions?