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 integration testing in seam using an in memory database integration testing in seam using an  embedded app server unit testing & easymock integration testing in seam selenium hudson groovy Q & A
@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... @Wikipedia:  a procedure used to validate that individual units of source code are working properly.
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. Easy to learn If you know Java, you have a head start Low fanfare  Uses the Java API Great for Testing
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 Integration testing is a logical extension of unit testing. In its simplest form, two units that have already been tested are combined into a component, and the interface between them is tested. 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 Portugese for “Coverage” A Code coverage tool Reports what's been executed and what hasn't Demo http://cobertura.sourceforge.net/
Selenium An acceptance testing tool. Built on javascript Tests can be written in variety of languages. Test can run on a variety of browsers. Slides don't do it justice, it's demo time. http://selenium.openqa.org/
Hudson A continous integration server. Listens to your version control software for updates. Runs your tests. Variety of great plugins. Very exciting and addicting...need....demo... 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.

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 Qualityof 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 endof an iteration demo time...or even worse, at deployment?
  • 4.
    The purpose ofour journey integration testing in seam using an in memory database integration testing in seam using an embedded app server unit testing & easymock integration testing in seam selenium hudson groovy Q & A
  • 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(StringfuzzyName) { 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.
    Unit Testing is...@Wikipedia: a procedure used to validate that individual units of source code are working properly.
  • 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 workingon 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
  • 13.
  • 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(StringfuzzyName) { 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 wetest for such dependencies without getting the whole system involved?
  • 17.
  • 18.
    “ Don't tellyour 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(StringfuzzyName) { 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 EntityManager: 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 EntityManager: 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 EntityManager: 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 EntityManager: 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 EntityManager: 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 EntityManager: 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 EntityManager: 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 EntityManager: 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);
  • 30.
  • 31.
    Groovy is anoptional (dynamic/static) typed language that you really should know. Easy to learn If you know Java, you have a head start Low fanfare Uses the Java API Great for Testing
  • 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.
    Integration Testing Integrationtesting is a logical extension of unit testing. In its simplest form, two units that have already been tested are combined into a component, and the interface between them is tested. has the best definition
  • 34.
    JBoss Seam hasa set of glorious tools to aid in integration testing
  • 35.
  • 36.
    public class FindAllAlbumsLikeArtistNameBeanIntegrationTestextends 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 withTest 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 withJSF Lifecycle Testing and Seam
  • 43.
  • 44.
    @Test public voidtestOneRequest() 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 conversationswith 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 withIntegration Mocks
  • 49.
    Paying for thereal 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 ofwhat some great open source products you should know about.
  • 53.
    CoberturA Portugese for“Coverage” A Code coverage tool Reports what's been executed and what hasn't Demo http://cobertura.sourceforge.net/
  • 54.
    Selenium An acceptancetesting tool. Built on javascript Tests can be written in variety of languages. Test can run on a variety of browsers. Slides don't do it justice, it's demo time. http://selenium.openqa.org/
  • 55.
    Hudson A continousintegration server. Listens to your version control software for updates. Runs your tests. Variety of great plugins. Very exciting and addicting...need....demo... https://hudson.dev.java.net/
  • 56.
    I'm kind oftired 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.