SlideShare a Scribd company logo
1 of 56
Testing  Seam  applications from the bottom up. Daniel “Danno” Hinojosa [email_address] http://www.evolutionnext.com Developer, Trainer, Consultant
Measuring the Quality of your code? How do you know your software works now? How will you know if your software works tomorrow? How will you know if your software works when...
It's the end of an iteration demo time...or even worse, at deployment?
The purpose of our journey ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
@Entity @Table(name = &quot;jsfone_album&quot;) public class Album { private Long id; private String name; private List<Artist> artists; .... } @Entity @Table(name = &quot;jsfone_artist&quot;) public class Artist { private Long id; private String name; private List<Album> albums; .... } Entities for this small project....Simple Album.java Artist.java
@Stateful @Name(&quot;findAllAlbumsLikeArtistNameBean&quot;) @Scope(ScopeType.CONVERSATION) public class FindAllAlbumsLikeArtistNameBean implements FindAllAlbumsLikeArtistNameLocal, FindAllAlbumsLikeArtistNameRemote { public static final String ejbQL =  &quot;SELECT album From Album album left “ + “ join album.artists as artist where “ + “ artist.name like :fuzzyName&quot;; private EntityManager entityManager; private List<Album> result; private String fuzzyName; @In public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } FindAllAlbumsLikeArtistNameBean.java
public void setName(String fuzzyName) { this.fuzzyName = fuzzyName; } @SuppressWarnings({&quot;unchecked&quot;}) public void find() { Query query = entityManager.createQuery(ejbQL); query.setParameter(&quot;fuzzyName&quot;, '%' + fuzzyName + '%'); result = (List<Album>) (List<?>) query.getResultList(); } @Factory(&quot;albums&quot;) public void initializeAlbums() { result = new ArrayList<Album>(); } @DataModel(&quot;albums&quot;) public List<Album> getResult() { return result; } @Remove @Destroy public void remove() { } } FindAllAlbumsLikeArtistNameBean.java  (Continued)
Unit Testing is... ,[object Object]
public class MyCalculator { public int add(int i, int j) { return i+j; } } MyCalculator.java public class MyCalculatorTest { @Test public void testNormal() { MyCalculator calc = new MyCalculator(); assertEquals(calc.add(22, 44), 66); } @Test public void testNegative() { MyCalculator calc = new MyCalculator(); assertEquals(calc.add(-2, 2), 0); } } MyCalculatorTest.java
public class MyCalculator { public int add(int i, int j) { return i+j; } } MyCalculator.java public class MyCalculatorTest { public void testNormal() { MyCalculator calc = new MyCalculator(); assertEquals(calc.add(22, 44), 66); } public void testNegative() { MyCalculator calc = new MyCalculator(); assertEquals(calc.add(-2, 2), 0); } } MyCalculatorTest.java
Aren't we working on something useful?
public class FindAllAlbumsLikeArtistNameBeanUnitTest { @Test public void unitTestFind() { FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean  = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); assertEquals(result.size(), ?); } } FindAllAlbumsLikeArtistNameBeanUnitTest.java First Attempt
Fail...NullPointerExceptions...
@Stateful @Name(&quot;findAllAlbumsLikeArtistNameBean&quot;) @Scope(ScopeType.CONVERSATION) public class FindAllAlbumsLikeArtistNameBean implements FindAllAlbumsLikeArtistNameLocal, FindAllAlbumsLikeArtistNameRemote { public static final String ejbQL =  &quot;SELECT album From Album album left “ + “ join album.artists as artist where “ + “ artist.name like :fuzzyName&quot;; private EntityManager entityManager; private List<Album> result; private String fuzzyName; @In public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } FindAllAlbumsLikeArtistNameBean.java
public void setName(String fuzzyName) { this.fuzzyName = fuzzyName; } @SuppressWarnings({&quot;unchecked&quot;}) public void find() { Query query = entityManager.createQuery(ejbQL); query.setParameter(&quot;fuzzyName&quot;, '%' + fuzzyName + '%'); result = (List<Album>) (List<?>) query.getResultList(); } @Factory(&quot;albums&quot;) public void initializeAlbums() { result = new ArrayList<Album>(); } @DataModel(&quot;albums&quot;) public List<Album> getResult() { return result; } @Remove @Destroy public void remove() { } } FindAllAlbumsLikeArtistNameBean.java  (Continued)
How do we test for such dependencies without getting the whole system involved?
Mocking
“ Don't tell your uncle what I said earlier about how he can't get a date because he bathes once a week and scratches himself in public, don't look at his unibrow, and only speak when spoken to.”
Easy Mock:  http://www.easymock.org
@Stateful @Name(&quot;findAllAlbumsLikeArtistNameBean&quot;) @Scope(ScopeType.CONVERSATION) public class FindAllAlbumsLikeArtistNameBean implements FindAllAlbumsLikeArtistNameLocal, FindAllAlbumsLikeArtistNameRemote { public static final String ejbQL =  &quot;SELECT album From Album album left “ + “ join album.artists as artist where “ + “ artist.name like :fuzzyName&quot;; private EntityManager entityManager; private List<Album> result; private String fuzzyName; @In public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } FindAllAlbumsLikeArtistNameBean.java For Review:
public void setName(String fuzzyName) { this.fuzzyName = fuzzyName; } @SuppressWarnings({&quot;unchecked&quot;}) public void find() { Query query = entityManager.createQuery(ejbQL); query.setParameter(&quot;fuzzyName&quot;, '%' + fuzzyName + '%'); result = (List<Album>) (List<?>) query.getResultList(); } @Factory(&quot;albums&quot;) public void initializeAlbums() { result = new ArrayList<Album>(); } @DataModel(&quot;albums&quot;) public List<Album> getResult() { return result; } @Remove @Destroy public void remove() { } } FindAllAlbumsLikeArtistNameBean.java  (Continued) For Review:
Mocking the Entity Manager: Creating Mocks for Dependencies List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
Mocking the Entity Manager: Instantiate Artifact  List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
Mocking the Entity Manager: Send in the Mock List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
Mocking the Entity Manager: Rehearse List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
Mocking the Entity Manager: Get it ready to react List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
Mocking the Entity Manager:  Go on, do it! do it! do it! List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
Mocking the Entity Manager: Assert that all is well. List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
Mocking the Entity Manager: Finally verify that it all worked. List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
Groovy: http://groovy.codehaus.org
Groovy is an optional (dynamic/static) typed language that you really should know. ,[object Object],[object Object],[object Object],[object Object],[object Object]
public class AlbumGroovyUnitTest { @Test (groups = [&quot;unit&quot;]) def testParameters() { println 'testing parameters in groovy' Artist artist = [:] as Artist artist.name = 'Duran Duran' artist.id = 9 assert artist.equals(artist) assert (!artist.equals(null)) assert (!artist.equals('foo')) def parameters = [ name: 'Madonna', albums: [new Album(name:'Like A Virgin'), new Album(name:'Holiday')] ] def madonna = new Artist(parameters); assert madonna.getAlbums().size() == 2 } } Quick Groovy Unit-Testing
Integration Testing ,[object Object],has the best definition
JBoss Seam has a set of glorious tools to aid in integration testing
Integration Testing with Seam
public class FindAllAlbumsLikeArtistNameBeanIntegrationTest extends SeamTest { @Test public void testBean() throws Exception { new ComponentTest() { @SuppressWarnings({&quot;unchecked&quot;}) protected void testComponents() throws Exception { setValue(&quot;#{findAllAlbumsLikeArtistNameBean.name}&quot;, &quot;Prince&quot;); invokeMethod(&quot;#{findAllAlbumsLikeArtistNameBean.find}&quot;); List<Album> albums = (List<Album>) (List<?>)  getValue(&quot;#{findAllAlbumsLikeArtistNameBean.result}&quot;); assertEquals(albums.size(), 0); } }.run(); } } FindAllAlbumsLikeArtistNameBeanIntegrationTest.java Cool factor is mucho high! A small app server actually runs!
Integration Testing with Test Data and Seam
@Entity @Table(name = &quot;jsfone_album&quot;) public class Album { private Long id; private String name; private List<Artist> artists; .... } @Entity @Table(name = &quot;jsfone_artist&quot;) public class Artist { private Long id; private String name; private List<Album> albums; .... } Entities for review Album.java Artist.java
<dataset> <jsfone_artist id=&quot;1&quot; name=&quot;Prince&quot;/> <jsfone_artist id=&quot;2&quot; name=&quot;Dean Martin&quot;/> <jsfone_artist id=&quot;3&quot; name=&quot;Black Sabbath&quot;/> <jsfone_album id=&quot;1&quot; name=&quot;1999&quot;/> <jsfone_album id=&quot;2&quot; name=&quot;Purple Rain&quot;/> <jsfone_album id=&quot;3&quot; name=&quot;The Very Best of Prince&quot;/> <jsfone_album id=&quot;4&quot; name=&quot;Italian Love Songs&quot;/> <jsfone_album id=&quot;5&quot; name=&quot;The Essential: Dean Martin&quot;/> <jsfone_album id=&quot;6&quot; name=&quot;Forever Cool&quot;/> <jsfone_album id=&quot;7&quot; name=&quot;We Sold Our Soul To Rock and Roll&quot;/> <jsfone_album id=&quot;8&quot; name=&quot;Black Sabbath&quot;/> <jsfone_album id=&quot;9&quot; name=&quot;Sabotage&quot;/> dbunit/loadartistalbumdata.xml
<jsfone_albumartists albumID=&quot;1&quot; artistID=&quot;1&quot;/> <jsfone_albumartists albumID=&quot;2&quot; artistID=&quot;1&quot;/> <jsfone_albumartists albumID=&quot;3&quot; artistID=&quot;1&quot;/> <jsfone_albumartists albumID=&quot;4&quot; artistID=&quot;2&quot;/> <jsfone_albumartists albumID=&quot;5&quot; artistID=&quot;2&quot;/> <jsfone_albumartists albumID=&quot;6&quot; artistID=&quot;2&quot;/> <jsfone_albumartists albumID=&quot;7&quot; artistID=&quot;3&quot;/> <jsfone_albumartists albumID=&quot;8&quot; artistID=&quot;3&quot;/> <jsfone_albumartists albumID=&quot;9&quot; artistID=&quot;3&quot;/> </dataset> dbunit/loadartistalbumdata.xml (Continued)
public class FindAllAlbumsLikeArtistNameBeanIntegrationWithDBTest  extends DBUnitSeamTest { @Test public void testStuff() throws Exception { new ComponentTest() { @SuppressWarnings({&quot;unchecked&quot;}) protected void testComponents() throws Exception { setValue(&quot;#{findAllAlbumsLikeArtistNameBean.name}&quot;, &quot;Prince&quot;); invokeMethod(&quot;#{findAllAlbumsLikeArtistNameBean.find}&quot;); List<Album> albums = (List<Album>) getValue(&quot;#{findAllAlbumsLikeArtistNameBean.result}&quot;); assertEquals(albums.get(0).getArtists().get(0).getName(), &quot;Prince&quot;); assertEquals(albums.size(), 3); } }.run(); } protected void prepareDBUnitOperations() { beforeTestOperations.add( new DataSetOperation(&quot;dbunit/loadartistalbumdata.xml&quot;) ); } } Cool factor is mucho higher people ! A small app server actually runs with test data! FindAllAlbumsLikeArtistNameBeanIntegrationWithDBTest.java
Test Integration with JSF Lifecycle Testing and Seam
The JSF Lifecycle
@Test public void testOneRequest() throws Exception { new NonFacesRequest (&quot;/findallalbumslikeartistname.xhtml&quot;) { protected void renderResponse() throws Exception { Object value = getValue(&quot;#{albums}&quot;); assertTrue(value != null); if (value instanceof DataModel) { DataModel albums = (DataModel) value; assertEquals(albums.getRowCount(), 0); return; } fail(&quot;Not a data model&quot;); } }.run(); FindAllAlbumsLikeArtistNameBeanPageTest.java A NonFacesRequest (“GET”)
new FacesRequest(&quot;/findallalbumslikeartistname.xhtml&quot;) { protected void updateModelValues() throws Exception { setValue(&quot;#{findAllAlbumsLikeArtistNameBean.name}&quot;,  &quot;Prince&quot;); } protected void invokeApplication() throws Exception {  invokeMethod(&quot;#{findAllAlbumsLikeArtistNameBean.find}&quot;); } protected void renderResponse() throws Exception { Object value = getValue(&quot;#{albums}&quot;); assertTrue(value != null); if (value instanceof DataModel) { DataModel albums = (DataModel) value; assertEquals(albums.getRowCount(), 3); } } }.run(); A Faces Request (“POST”) FindAllAlbumsLikeArtistNameBeanPageTest.java
Testing for conversations with JSF Lifcycle Testing and Seam
public void testConversation() throws Exception { String  conversationId  = new NonFacesRequest (&quot;/processName.xhtml&quot;) {....} }.run(); new FacesRequest (&quot;/processName.xhtml&quot;,  conversationId ) {....} }.run(); new NonFacesRequest (&quot;/processExperience.xhtml&quot;,  conversationId ) {....} }.run(); new FacesRequest (&quot;/processExperience.xhtml&quot;,  conversationId ) {....} }.run(); new NonFacesRequest (&quot;/thankyou.xhtml&quot;,  conversationId ) {....} }.run(); } Conversation Testing
Seam Testing with Integration Mocks
Paying for the real thing can be expensive: @Stateless @Name(&quot;creditCardApprover&quot;) @Scope(ScopeType.STATELESS) public class CreditCardApproverBean implements  CreditCardApproverLocal, CreditCardApproverRemote { @Logger Log log; public boolean approve(String creditCardNumber, int month, int year, int cvv2) { log.debug(&quot;Thanks for processing, you have now been charged $.10&quot;); return true; } } CreditCardApproverBean.java
@Stateless @Name(&quot;creditCardApprover&quot;) @Scope(ScopeType.STATELESS) @Install(precedence = MOCK) public class CreditCardApproverMockBean implements CreditCardApproverLocal, CreditCardApproverRemote { public boolean approve(String creditCardNumber, int month, int year, int cvv2) { return creditCardNumber.endsWith(&quot;2222&quot;); } } But paying an integration mock, or as I like to call it, an imposter, is cheap. CreditCardApproverMockBean.java
@Stateless @Name(&quot;processPaymentBean&quot;) @Scope(ScopeType.EVENT) public class ProcessPaymentBean implements ProcessPaymentLocal, ProcessPaymentRemote { private CreditCardApprover creditCardApprover; private String creditCardNumber; private int year; private int month; private int cvv2; @In(value = &quot;creditCardApprover&quot;, create = true) public void setCreditCardApprover(CreditCardApprover creditCardApprover) { this.creditCardApprover = creditCardApprover; } //Getters and setters for year, month, cvv2 assumed public boolean process() { return creditCardApprover.approve(creditCardNumber, month, year, cvv2); } } Assuming we have interface driven design....Mocks win in integration ProcessPaymentBean.java
A review of what some great open source products you should know about.
CoberturA ,[object Object],[object Object],[object Object],[object Object],http://cobertura.sourceforge.net/
Selenium ,[object Object],[object Object],[object Object],[object Object],[object Object],http://selenium.openqa.org/
Hudson ,[object Object],[object Object],[object Object],[object Object],[object Object],https://hudson.dev.java.net/
I'm kind of tired now, I think I'm gonna go home..... .... but Mama always says leave time for Q&A.  She says it's the right thing to do.

More Related Content

What's hot

Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)andrewnacin
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineRaimonds Simanovskis
 
EuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystifiedEuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystifiedPablo Enfedaque
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creationbenalman
 
Amazing SQL your ORM can (or can't) do | PGConf EU 2019 | Louise Grandjonc
Amazing SQL your ORM can (or can't) do | PGConf EU 2019 | Louise GrandjoncAmazing SQL your ORM can (or can't) do | PGConf EU 2019 | Louise Grandjonc
Amazing SQL your ORM can (or can't) do | PGConf EU 2019 | Louise GrandjoncCitus Data
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design PatternsRobert Casanova
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Hack in the Box Keynote 2006
Hack in the Box Keynote 2006Hack in the Box Keynote 2006
Hack in the Box Keynote 2006Mark Curphey
 
SilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript RefactoringSilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript RefactoringIngo Schommer
 
GoCracow #5 Bartlomiej klimczak - GoBDD
GoCracow #5 Bartlomiej klimczak - GoBDDGoCracow #5 Bartlomiej klimczak - GoBDD
GoCracow #5 Bartlomiej klimczak - GoBDDBartłomiej Kiełbasa
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with JasmineTim Tyrrell
 
Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHPMarcello Duarte
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmineRubyc Slides
 
An Introduction to the World of Testing for Front-End Developers
An Introduction to the World of Testing for Front-End DevelopersAn Introduction to the World of Testing for Front-End Developers
An Introduction to the World of Testing for Front-End DevelopersFITC
 

What's hot (20)

Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
 
EuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystifiedEuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystified
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creation
 
Amazing SQL your ORM can (or can't) do | PGConf EU 2019 | Louise Grandjonc
Amazing SQL your ORM can (or can't) do | PGConf EU 2019 | Louise GrandjoncAmazing SQL your ORM can (or can't) do | PGConf EU 2019 | Louise Grandjonc
Amazing SQL your ORM can (or can't) do | PGConf EU 2019 | Louise Grandjonc
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design Patterns
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Hack in the Box Keynote 2006
Hack in the Box Keynote 2006Hack in the Box Keynote 2006
Hack in the Box Keynote 2006
 
Perl basics for Pentesters
Perl basics for PentestersPerl basics for Pentesters
Perl basics for Pentesters
 
SilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript RefactoringSilverStripe CMS JavaScript Refactoring
SilverStripe CMS JavaScript Refactoring
 
GoCracow #5 Bartlomiej klimczak - GoBDD
GoCracow #5 Bartlomiej klimczak - GoBDDGoCracow #5 Bartlomiej klimczak - GoBDD
GoCracow #5 Bartlomiej klimczak - GoBDD
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 
Angular mix chrisnoring
Angular mix chrisnoringAngular mix chrisnoring
Angular mix chrisnoring
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with Jasmine
 
Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHP
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmine
 
An Introduction to the World of Testing for Front-End Developers
An Introduction to the World of Testing for Front-End DevelopersAn Introduction to the World of Testing for Front-End Developers
An Introduction to the World of Testing for Front-End Developers
 

Viewers also liked

Jbossworld Presentation
Jbossworld PresentationJbossworld Presentation
Jbossworld PresentationDan Hinojosa
 
Scala Demystifying the Funky Stuff
Scala Demystifying the Funky StuffScala Demystifying the Funky Stuff
Scala Demystifying the Funky StuffDan Hinojosa
 
50 EJB 3 Best Practices in 50 Minutes - JavaOne 2014
50 EJB 3 Best Practices in 50 Minutes - JavaOne 201450 EJB 3 Best Practices in 50 Minutes - JavaOne 2014
50 EJB 3 Best Practices in 50 Minutes - JavaOne 2014Ryan Cuprak
 
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...ENSET, Université Hassan II Casablanca
 
Study: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsStudy: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsLinkedIn
 

Viewers also liked (6)

Ejb3 Dan Hinojosa
Ejb3 Dan HinojosaEjb3 Dan Hinojosa
Ejb3 Dan Hinojosa
 
Jbossworld Presentation
Jbossworld PresentationJbossworld Presentation
Jbossworld Presentation
 
Scala Demystifying the Funky Stuff
Scala Demystifying the Funky StuffScala Demystifying the Funky Stuff
Scala Demystifying the Funky Stuff
 
50 EJB 3 Best Practices in 50 Minutes - JavaOne 2014
50 EJB 3 Best Practices in 50 Minutes - JavaOne 201450 EJB 3 Best Practices in 50 Minutes - JavaOne 2014
50 EJB 3 Best Practices in 50 Minutes - JavaOne 2014
 
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
 
Study: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsStudy: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving Cars
 

Similar to Testing Jboss Seam Bottom Up

Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryMauro Rocco
 
Java Boilerplate Busters
Java Boilerplate BustersJava Boilerplate Busters
Java Boilerplate BustersHamletDRC
 
Java Boilerplate Busters
Java Boilerplate BustersJava Boilerplate Busters
Java Boilerplate BustersHamletDRC
 
Using DAOs without implementing them
Using DAOs without implementing themUsing DAOs without implementing them
Using DAOs without implementing thembenfante
 
Writing Apps the Google-y Way
Writing Apps the Google-y WayWriting Apps the Google-y Way
Writing Apps the Google-y WayPamela Fox
 
Python - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave ParkPython - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave Parkpointstechgeeks
 
Perl Teach-In (part 1)
Perl Teach-In (part 1)Perl Teach-In (part 1)
Perl Teach-In (part 1)Dave Cross
 
Test du futur avec Spock
Test du futur avec SpockTest du futur avec Spock
Test du futur avec SpockCARA_Lyon
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With PhpJeremy Coates
 
Php Using Arrays
Php Using ArraysPhp Using Arrays
Php Using Arraysmussawir20
 
Effective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsEffective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsMarakana Inc.
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the typeWim Godden
 

Similar to Testing Jboss Seam Bottom Up (20)

Scala introduction
Scala introductionScala introduction
Scala introduction
 
Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & Celery
 
Java Boilerplate Busters
Java Boilerplate BustersJava Boilerplate Busters
Java Boilerplate Busters
 
Java Boilerplate Busters
Java Boilerplate BustersJava Boilerplate Busters
Java Boilerplate Busters
 
Fantom and Tales
Fantom and TalesFantom and Tales
Fantom and Tales
 
My java file
My java fileMy java file
My java file
 
Using DAOs without implementing them
Using DAOs without implementing themUsing DAOs without implementing them
Using DAOs without implementing them
 
Writing Apps the Google-y Way
Writing Apps the Google-y WayWriting Apps the Google-y Way
Writing Apps the Google-y Way
 
Introduction to JQuery
Introduction to JQueryIntroduction to JQuery
Introduction to JQuery
 
Python - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave ParkPython - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave Park
 
JQuery Basics
JQuery BasicsJQuery Basics
JQuery Basics
 
Perl Teach-In (part 1)
Perl Teach-In (part 1)Perl Teach-In (part 1)
Perl Teach-In (part 1)
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Test du futur avec Spock
Test du futur avec SpockTest du futur avec Spock
Test du futur avec Spock
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With Php
 
Php Using Arrays
Php Using ArraysPhp Using Arrays
Php Using Arrays
 
Effective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsEffective Java - Still Effective After All These Years
Effective Java - Still Effective After All These Years
 
displaytag
displaytagdisplaytag
displaytag
 
JavaScript Needn't Hurt!
JavaScript Needn't Hurt!JavaScript Needn't Hurt!
JavaScript Needn't Hurt!
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the type
 

Recently uploaded

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 

Recently uploaded (20)

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 

Testing Jboss Seam Bottom Up

  • 1. Testing Seam applications from the bottom up. Daniel “Danno” Hinojosa [email_address] http://www.evolutionnext.com Developer, Trainer, Consultant
  • 2. Measuring the Quality of your code? How do you know your software works now? How will you know if your software works tomorrow? How will you know if your software works when...
  • 3. It's the end of an iteration demo time...or even worse, at deployment?
  • 4.
  • 5. @Entity @Table(name = &quot;jsfone_album&quot;) public class Album { private Long id; private String name; private List<Artist> artists; .... } @Entity @Table(name = &quot;jsfone_artist&quot;) public class Artist { private Long id; private String name; private List<Album> albums; .... } Entities for this small project....Simple Album.java Artist.java
  • 6. @Stateful @Name(&quot;findAllAlbumsLikeArtistNameBean&quot;) @Scope(ScopeType.CONVERSATION) public class FindAllAlbumsLikeArtistNameBean implements FindAllAlbumsLikeArtistNameLocal, FindAllAlbumsLikeArtistNameRemote { public static final String ejbQL = &quot;SELECT album From Album album left “ + “ join album.artists as artist where “ + “ artist.name like :fuzzyName&quot;; private EntityManager entityManager; private List<Album> result; private String fuzzyName; @In public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } FindAllAlbumsLikeArtistNameBean.java
  • 7. public void setName(String fuzzyName) { this.fuzzyName = fuzzyName; } @SuppressWarnings({&quot;unchecked&quot;}) public void find() { Query query = entityManager.createQuery(ejbQL); query.setParameter(&quot;fuzzyName&quot;, '%' + fuzzyName + '%'); result = (List<Album>) (List<?>) query.getResultList(); } @Factory(&quot;albums&quot;) public void initializeAlbums() { result = new ArrayList<Album>(); } @DataModel(&quot;albums&quot;) public List<Album> getResult() { return result; } @Remove @Destroy public void remove() { } } FindAllAlbumsLikeArtistNameBean.java (Continued)
  • 8.
  • 9. public class MyCalculator { public int add(int i, int j) { return i+j; } } MyCalculator.java public class MyCalculatorTest { @Test public void testNormal() { MyCalculator calc = new MyCalculator(); assertEquals(calc.add(22, 44), 66); } @Test public void testNegative() { MyCalculator calc = new MyCalculator(); assertEquals(calc.add(-2, 2), 0); } } MyCalculatorTest.java
  • 10. public class MyCalculator { public int add(int i, int j) { return i+j; } } MyCalculator.java public class MyCalculatorTest { public void testNormal() { MyCalculator calc = new MyCalculator(); assertEquals(calc.add(22, 44), 66); } public void testNegative() { MyCalculator calc = new MyCalculator(); assertEquals(calc.add(-2, 2), 0); } } MyCalculatorTest.java
  • 11. Aren't we working on something useful?
  • 12. public class FindAllAlbumsLikeArtistNameBeanUnitTest { @Test public void unitTestFind() { FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); assertEquals(result.size(), ?); } } FindAllAlbumsLikeArtistNameBeanUnitTest.java First Attempt
  • 14. @Stateful @Name(&quot;findAllAlbumsLikeArtistNameBean&quot;) @Scope(ScopeType.CONVERSATION) public class FindAllAlbumsLikeArtistNameBean implements FindAllAlbumsLikeArtistNameLocal, FindAllAlbumsLikeArtistNameRemote { public static final String ejbQL = &quot;SELECT album From Album album left “ + “ join album.artists as artist where “ + “ artist.name like :fuzzyName&quot;; private EntityManager entityManager; private List<Album> result; private String fuzzyName; @In public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } FindAllAlbumsLikeArtistNameBean.java
  • 15. public void setName(String fuzzyName) { this.fuzzyName = fuzzyName; } @SuppressWarnings({&quot;unchecked&quot;}) public void find() { Query query = entityManager.createQuery(ejbQL); query.setParameter(&quot;fuzzyName&quot;, '%' + fuzzyName + '%'); result = (List<Album>) (List<?>) query.getResultList(); } @Factory(&quot;albums&quot;) public void initializeAlbums() { result = new ArrayList<Album>(); } @DataModel(&quot;albums&quot;) public List<Album> getResult() { return result; } @Remove @Destroy public void remove() { } } FindAllAlbumsLikeArtistNameBean.java (Continued)
  • 16. How do we test for such dependencies without getting the whole system involved?
  • 18. “ Don't tell your uncle what I said earlier about how he can't get a date because he bathes once a week and scratches himself in public, don't look at his unibrow, and only speak when spoken to.”
  • 19. Easy Mock: http://www.easymock.org
  • 20. @Stateful @Name(&quot;findAllAlbumsLikeArtistNameBean&quot;) @Scope(ScopeType.CONVERSATION) public class FindAllAlbumsLikeArtistNameBean implements FindAllAlbumsLikeArtistNameLocal, FindAllAlbumsLikeArtistNameRemote { public static final String ejbQL = &quot;SELECT album From Album album left “ + “ join album.artists as artist where “ + “ artist.name like :fuzzyName&quot;; private EntityManager entityManager; private List<Album> result; private String fuzzyName; @In public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } FindAllAlbumsLikeArtistNameBean.java For Review:
  • 21. public void setName(String fuzzyName) { this.fuzzyName = fuzzyName; } @SuppressWarnings({&quot;unchecked&quot;}) public void find() { Query query = entityManager.createQuery(ejbQL); query.setParameter(&quot;fuzzyName&quot;, '%' + fuzzyName + '%'); result = (List<Album>) (List<?>) query.getResultList(); } @Factory(&quot;albums&quot;) public void initializeAlbums() { result = new ArrayList<Album>(); } @DataModel(&quot;albums&quot;) public List<Album> getResult() { return result; } @Remove @Destroy public void remove() { } } FindAllAlbumsLikeArtistNameBean.java (Continued) For Review:
  • 22. Mocking the Entity Manager: Creating Mocks for Dependencies List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
  • 23. Mocking the Entity Manager: Instantiate Artifact List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
  • 24. Mocking the Entity Manager: Send in the Mock List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
  • 25. Mocking the Entity Manager: Rehearse List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
  • 26. Mocking the Entity Manager: Get it ready to react List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
  • 27. Mocking the Entity Manager: Go on, do it! do it! do it! List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
  • 28. Mocking the Entity Manager: Assert that all is well. List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
  • 29. Mocking the Entity Manager: Finally verify that it all worked. List<Album> fakeAlbums = new ArrayList<Album>(); fakeAlbums.add(new Album(&quot;Purple Rain&quot;)); fakeAlbums.add(new Album(&quot;1999&quot;)); EntityManager entityManager = createMock(EntityManager.class); Query query = createMock(Query.class); FindAllAlbumsLikeArtistNameBean findAllAlbumsLikeArtistNameBean = new FindAllAlbumsLikeArtistNameBean(); findAllAlbumsLikeArtistNameBean.setEntityManager(entityManager); expect(entityManager.createQuery(FindAllAlbumsLikeArtistNameBean.ejbQL)). andReturn(query); expect(query.setParameter(&quot;fuzzyName&quot;, &quot;%Prince%&quot;)).andReturn(query); expect(query.getResultList()).andReturn(fakeAlbums); replay(entityManager); replay(query); findAllAlbumsLikeArtistNameBean.setName(&quot;Prince&quot;); findAllAlbumsLikeArtistNameBean.find(); List<Album> result = findAllAlbumsLikeArtistNameBean.getResult(); assertEquals(result.size(), 2); verify(entityManager); verify(query);
  • 31.
  • 32. public class AlbumGroovyUnitTest { @Test (groups = [&quot;unit&quot;]) def testParameters() { println 'testing parameters in groovy' Artist artist = [:] as Artist artist.name = 'Duran Duran' artist.id = 9 assert artist.equals(artist) assert (!artist.equals(null)) assert (!artist.equals('foo')) def parameters = [ name: 'Madonna', albums: [new Album(name:'Like A Virgin'), new Album(name:'Holiday')] ] def madonna = new Artist(parameters); assert madonna.getAlbums().size() == 2 } } Quick Groovy Unit-Testing
  • 33.
  • 34. JBoss Seam has a set of glorious tools to aid in integration testing
  • 36. public class FindAllAlbumsLikeArtistNameBeanIntegrationTest extends SeamTest { @Test public void testBean() throws Exception { new ComponentTest() { @SuppressWarnings({&quot;unchecked&quot;}) protected void testComponents() throws Exception { setValue(&quot;#{findAllAlbumsLikeArtistNameBean.name}&quot;, &quot;Prince&quot;); invokeMethod(&quot;#{findAllAlbumsLikeArtistNameBean.find}&quot;); List<Album> albums = (List<Album>) (List<?>) getValue(&quot;#{findAllAlbumsLikeArtistNameBean.result}&quot;); assertEquals(albums.size(), 0); } }.run(); } } FindAllAlbumsLikeArtistNameBeanIntegrationTest.java Cool factor is mucho high! A small app server actually runs!
  • 37. Integration Testing with Test Data and Seam
  • 38. @Entity @Table(name = &quot;jsfone_album&quot;) public class Album { private Long id; private String name; private List<Artist> artists; .... } @Entity @Table(name = &quot;jsfone_artist&quot;) public class Artist { private Long id; private String name; private List<Album> albums; .... } Entities for review Album.java Artist.java
  • 39. <dataset> <jsfone_artist id=&quot;1&quot; name=&quot;Prince&quot;/> <jsfone_artist id=&quot;2&quot; name=&quot;Dean Martin&quot;/> <jsfone_artist id=&quot;3&quot; name=&quot;Black Sabbath&quot;/> <jsfone_album id=&quot;1&quot; name=&quot;1999&quot;/> <jsfone_album id=&quot;2&quot; name=&quot;Purple Rain&quot;/> <jsfone_album id=&quot;3&quot; name=&quot;The Very Best of Prince&quot;/> <jsfone_album id=&quot;4&quot; name=&quot;Italian Love Songs&quot;/> <jsfone_album id=&quot;5&quot; name=&quot;The Essential: Dean Martin&quot;/> <jsfone_album id=&quot;6&quot; name=&quot;Forever Cool&quot;/> <jsfone_album id=&quot;7&quot; name=&quot;We Sold Our Soul To Rock and Roll&quot;/> <jsfone_album id=&quot;8&quot; name=&quot;Black Sabbath&quot;/> <jsfone_album id=&quot;9&quot; name=&quot;Sabotage&quot;/> dbunit/loadartistalbumdata.xml
  • 40. <jsfone_albumartists albumID=&quot;1&quot; artistID=&quot;1&quot;/> <jsfone_albumartists albumID=&quot;2&quot; artistID=&quot;1&quot;/> <jsfone_albumartists albumID=&quot;3&quot; artistID=&quot;1&quot;/> <jsfone_albumartists albumID=&quot;4&quot; artistID=&quot;2&quot;/> <jsfone_albumartists albumID=&quot;5&quot; artistID=&quot;2&quot;/> <jsfone_albumartists albumID=&quot;6&quot; artistID=&quot;2&quot;/> <jsfone_albumartists albumID=&quot;7&quot; artistID=&quot;3&quot;/> <jsfone_albumartists albumID=&quot;8&quot; artistID=&quot;3&quot;/> <jsfone_albumartists albumID=&quot;9&quot; artistID=&quot;3&quot;/> </dataset> dbunit/loadartistalbumdata.xml (Continued)
  • 41. public class FindAllAlbumsLikeArtistNameBeanIntegrationWithDBTest extends DBUnitSeamTest { @Test public void testStuff() throws Exception { new ComponentTest() { @SuppressWarnings({&quot;unchecked&quot;}) protected void testComponents() throws Exception { setValue(&quot;#{findAllAlbumsLikeArtistNameBean.name}&quot;, &quot;Prince&quot;); invokeMethod(&quot;#{findAllAlbumsLikeArtistNameBean.find}&quot;); List<Album> albums = (List<Album>) getValue(&quot;#{findAllAlbumsLikeArtistNameBean.result}&quot;); assertEquals(albums.get(0).getArtists().get(0).getName(), &quot;Prince&quot;); assertEquals(albums.size(), 3); } }.run(); } protected void prepareDBUnitOperations() { beforeTestOperations.add( new DataSetOperation(&quot;dbunit/loadartistalbumdata.xml&quot;) ); } } Cool factor is mucho higher people ! A small app server actually runs with test data! FindAllAlbumsLikeArtistNameBeanIntegrationWithDBTest.java
  • 42. Test Integration with JSF Lifecycle Testing and Seam
  • 44. @Test public void testOneRequest() throws Exception { new NonFacesRequest (&quot;/findallalbumslikeartistname.xhtml&quot;) { protected void renderResponse() throws Exception { Object value = getValue(&quot;#{albums}&quot;); assertTrue(value != null); if (value instanceof DataModel) { DataModel albums = (DataModel) value; assertEquals(albums.getRowCount(), 0); return; } fail(&quot;Not a data model&quot;); } }.run(); FindAllAlbumsLikeArtistNameBeanPageTest.java A NonFacesRequest (“GET”)
  • 45. new FacesRequest(&quot;/findallalbumslikeartistname.xhtml&quot;) { protected void updateModelValues() throws Exception { setValue(&quot;#{findAllAlbumsLikeArtistNameBean.name}&quot;, &quot;Prince&quot;); } protected void invokeApplication() throws Exception { invokeMethod(&quot;#{findAllAlbumsLikeArtistNameBean.find}&quot;); } protected void renderResponse() throws Exception { Object value = getValue(&quot;#{albums}&quot;); assertTrue(value != null); if (value instanceof DataModel) { DataModel albums = (DataModel) value; assertEquals(albums.getRowCount(), 3); } } }.run(); A Faces Request (“POST”) FindAllAlbumsLikeArtistNameBeanPageTest.java
  • 46. Testing for conversations with JSF Lifcycle Testing and Seam
  • 47. public void testConversation() throws Exception { String conversationId = new NonFacesRequest (&quot;/processName.xhtml&quot;) {....} }.run(); new FacesRequest (&quot;/processName.xhtml&quot;, conversationId ) {....} }.run(); new NonFacesRequest (&quot;/processExperience.xhtml&quot;, conversationId ) {....} }.run(); new FacesRequest (&quot;/processExperience.xhtml&quot;, conversationId ) {....} }.run(); new NonFacesRequest (&quot;/thankyou.xhtml&quot;, conversationId ) {....} }.run(); } Conversation Testing
  • 48. Seam Testing with Integration Mocks
  • 49. Paying for the real thing can be expensive: @Stateless @Name(&quot;creditCardApprover&quot;) @Scope(ScopeType.STATELESS) public class CreditCardApproverBean implements CreditCardApproverLocal, CreditCardApproverRemote { @Logger Log log; public boolean approve(String creditCardNumber, int month, int year, int cvv2) { log.debug(&quot;Thanks for processing, you have now been charged $.10&quot;); return true; } } CreditCardApproverBean.java
  • 50. @Stateless @Name(&quot;creditCardApprover&quot;) @Scope(ScopeType.STATELESS) @Install(precedence = MOCK) public class CreditCardApproverMockBean implements CreditCardApproverLocal, CreditCardApproverRemote { public boolean approve(String creditCardNumber, int month, int year, int cvv2) { return creditCardNumber.endsWith(&quot;2222&quot;); } } But paying an integration mock, or as I like to call it, an imposter, is cheap. CreditCardApproverMockBean.java
  • 51. @Stateless @Name(&quot;processPaymentBean&quot;) @Scope(ScopeType.EVENT) public class ProcessPaymentBean implements ProcessPaymentLocal, ProcessPaymentRemote { private CreditCardApprover creditCardApprover; private String creditCardNumber; private int year; private int month; private int cvv2; @In(value = &quot;creditCardApprover&quot;, create = true) public void setCreditCardApprover(CreditCardApprover creditCardApprover) { this.creditCardApprover = creditCardApprover; } //Getters and setters for year, month, cvv2 assumed public boolean process() { return creditCardApprover.approve(creditCardNumber, month, year, cvv2); } } Assuming we have interface driven design....Mocks win in integration ProcessPaymentBean.java
  • 52. A review of what some great open source products you should know about.
  • 53.
  • 54.
  • 55.
  • 56. I'm kind of tired now, I think I'm gonna go home..... .... but Mama always says leave time for Q&A. She says it's the right thing to do.