Tony,

The purpose of unit testing is to run your tests in a black box
environment.  If you auto-load all of the Spring configurations from
your web.xml and use them, you're kind of defeating the purpose of unit
testing.

If you're looking for integration testing (which it sounds like you
are), then you should probably look here:

http://tapestry.apache.org/tapestry5/tapestry-test/

I'll assume you really do mean unit testing though.  Tapestry provides
very clean hooks to unit test your pages.  I've implemented a variation
of the techniques found on the Wiki... The main difference being that
you get to use the traditional Tapestry annotations.  The real power of
this is that I can maintain an entirely separate Spring configuration
that contains mock objects (called "test-applicationContext.xml" in the
code below).

Hope this helps,

Joel


Here's the code:


/******* PageTestSupport.java *******/

package com.myapp.dir.pages;

import org.apache.tapestry.test.PageTester;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;

public abstract class PageTestSupport {

        protected PageTester pageTester;
        
        @BeforeTest(alwaysRun=true)
        protected void init() {
                //crucial line... Looks for a 'TestHarnessModule' in the
com.myapp.dir.services package
                pageTester= new PageTester("com.myapp.dir",
"TestHarness");
        }
                        
        @AfterTest(alwaysRun=true)
        protected void destroy() {
                pageTester.shutdown();
        }
        
}


/******* TestHarnessModule.java *******/

package com.myapp.dir.services;

import org.apache.tapestry.ioc.ObjectLocator;
import org.apache.tapestry.ioc.ObjectProvider;
import org.apache.tapestry.ioc.OrderedConfiguration;

public class TestHarnessModule {

        // contribution master object provider
        public static void contributeMasterObjectProvider(
                        OrderedConfiguration<ObjectProvider>
configuration,
                        ObjectLocator locator) {
                configuration.add("spring", locator
                                .autobuild(SpringObjectProvider.class));
        }
}


/******* SpringObjectProvider.java *******/

package com.myapp.dir.services;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.tapestry.ioc.AnnotationProvider;
import org.apache.tapestry.ioc.ObjectLocator;
import org.apache.tapestry.ioc.ObjectProvider;
import org.apache.tapestry.ioc.annotations.Inject;
import org.apache.tapestry.ioc.annotations.InjectService;
import org.apache.tapestry.ioc.services.TypeCoercer;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringObjectProvider implements ObjectProvider {

        private TypeCoercer typeCoercer;

        private ApplicationContext context;
        
        private static final Logger logger =
Logger.getLogger(SpringObjectProvider.class.getName());

        public SpringObjectProvider(@InjectService("TypeCoercer")
        TypeCoercer typeCoercer) {
                this.typeCoercer = typeCoercer;
        }

        /**
         * @see
org.apache.tapestry.ioc.ObjectProvider#provide(java.lang.Class,
         *      org.apache.tapestry.ioc.AnnotationProvider,
         *      org.apache.tapestry.ioc.ObjectLocator)
         */
        public <T> T provide(Class<T> objectType,
                        AnnotationProvider annotationProvider,
ObjectLocator locator) {

                //hack...
                if
(objectType.getName().startsWith("org.apache.tapestry")) {
                        return null;
                }

                Inject annotation =
annotationProvider.getAnnotation(Inject.class);

                if (annotation == null)
                        return null;

                Object obj = null;

                try {
                        String[] beanNames =
getSpringContext().getBeanNamesForType(objectType);
                        
                        if(beanNames.length > 0) {
                                //return first result
                                obj =
getSpringContext().getBean(beanNames[0]);
                        } else {
                                logger.info("Couldn't find a bean for
type " + objectType.getName());
                        }
                } catch (Exception e) {
                        logger.log(Level.WARNING, "Problem occurred when
finding a bean for type " + objectType.getName(), e);
                }

                T coerced = typeCoercer.coerce(obj, objectType);

                return coerced;

        }

        private ApplicationContext getSpringContext() {
                if (context == null) {
                        context = new ClassPathXmlApplicationContext(
                                        new String[] {
"test-applicationContext.xml" });
                }

                return context;
        }

}


-----Original Message-----
From: Tony Green [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, December 11, 2007 6:24 AM
To: users@tapestry.apache.org
Subject: unit testing

I have two questions about unit testing with tapestry.

 

I am trying to create a setup where I can unit test pages using
appropriate mocks and stubs for injected business services whether they
come from Tapestry IOC or Spring.

 

I've seen the Wiki entries for SpringIntegrationAlternative and
SpringIntegrationAlternative2.  This doesn't seem to be a totally
natural solution - in the case of alternative 2 I have to change my
injection annotations to get spring beans in a testing context.  We are
currently using 5.0.7 snapshot for evaluation - I'm wondering if there
is going to be a fully integrated solution going forward?

 

Secondly how can I mock out components injected into the container (from
both Tapeestry and Spring) underneath a PageTester instance?  I notice
there's an IOCTestCase and a TapestryTestCase in the source - am I
looking the right direction?

 

Thx.T.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to