avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stuart Roebuck <stuart.roeb...@adolos.co.uk>
Subject Re: JUnit AvalonTestCase
Date Thu, 09 Aug 2001 09:15:24 GMT
Funnily enough I spent Tuesday working out a solution for this kind of 
issue for a Cocoon Action I'm working on at the moment.

I went for a 'mock' object approach [see 
<http://mockobjects.sourceforge.net/endotesting.html>], creating mock 
versions of (for my case) Redirector, Request, Session, Source and 
SourceResolver.  These all represent the simplest possible implementations 
of the interfaces, which pass back results that I pre-set with additional 
set methods.  I like this approach because it's very simple, very flexible 
and transparent, and the mock objects can potentially grow in the source 
base alongside the test cases.

Here's an example of a bit of one of the resulting testcases:

> public class SessionHandlerTest extends TestCase {
>     private SessionHandler handler;
>     private SessionMock session;
>     private Redirector redirector;
>     private SourceResolver sourceResolver;
>     private RequestMock request;
>     private Parameters parameters;
>     private Map objectModel;
>     public SessionHandlerTest(String name) {
>         super(name);
>     }
>     public void setUp() {
>         this.handler = new SessionHandler();
>         this.session = new SessionMock();
>         this.redirector = new RedirectorMock();
>         this.sourceResolver = new SourceResolverMock();
>         this.request = new RequestMock();
>         this.parameters = new Parameters();
>         this.objectModel = new HashMap();
>         this.objectModel.put(Constants.REQUEST_OBJECT, this.request);
>     }

>     /**
>      * Check that a form field of "login=sessionHandler" is required for 
> successful
>      * login.
>      */
>     public void testActLoginSessionHandlerField() throws Exception {
>         setupValidLoginAttempt();
>         this.request.mockRemoveParameter("login");
>         Map map = handler.act(this.redirector, this.sourceResolver, this.
> objectModel, "src", this.parameters);
>         assertNull("Action should return null to indicate rejected login"
> , map);
>     }
>     private void setupValidLoginAttempt() {
>         this.request.mockSetParameter("login","sessionHandler");
>         this.request.mockSetParameter("username","valid");
>         this.request.mockSetParameter("password","user");
>         this.parameters.setParameter("accept-login","true");
>         this.parameters.setParameter("require-secure-login","true");
>         this.parameters.setParameter("required-login-
> parameters","username,password");
>         this.session.setAttribute("sessionhandler/original_uri","testpage"
> );
>         this.request.mockSetSecure(true);
>         this.request.mockSetSession(this.session);
>     }

My personal feeling is that setting up specialized TestCases for testing, 
whilst it may simplify the code of tests for people familiar with the code,
  removes transparency and adds a level of complexity into the test cases 
that could make them harder to maintain. e.g. you need to look at the 
definition of the new TestCase in order to determine what the pre-set 
state is and then learn the new methods for altering it.  With plain Mock 
classes you have to explicitly setup everything in the TestCase which may 
require more lines of code (but then you can easily do a copy and paste 
job from a previous test case), however, you end up with a test case that 
is self contained and self documenting.  The only new methods you need to 
learn are additional methods in the mock classes that provide setup or 
validation functionality.


PS. I'm intending feeding back the mock objects to Cocoon if folk are 

On Thursday, August 9, 2001, at 06:31  am, giacomo wrote:

> I've followed the discussion about dropping Testlet in favor of JUnit
> with great interest.
> What I think is missing in this area of unit tests of Avalon
> components are specialized TestCases.
> The idea came when I was looking at the DataSourceTestCase (and wanted
> to adapt it for my own components). When one needs to test Components
> you'll mostly need to create a logger (Loggable), maybe a Context
> (Contextualizable), a Configuration object (Configurable) and sometimes
> also a ComponentManager (Composer). And at least here where you have to
> test a Composer you probably wish to have a CM setup easily. This is
> what the aforementioned TestCases should set up for you.
> If there is interest I'd like to contribute specialized JUnit
> TestCases for Avalon. I initially thought of two TestCases:
> FrameworkTestCase (uses framework.component.DefaultComponentManager)
> ExcaliburTestCase (uses excalibur.component.ExcaliburComponentManager)
> The discussion I'd like to make is about how things like Context,
> Configuration (be it an already created Configuration object, a String
> or a File containing the configuration) and the roles got passed into
> the TestCase for setup of the CM. The possibilities are:
> Constructor:
> 	This would set it up once for every test in the class but
> 	gives no possibility to change it (ie. Configuration,
> 	Context) for different tests.
> separate method:
> 	This would allow to use it as a test case itself and it
> 	could be called every time you need to change something.
> setup/tearDown method:
> 	This would set up the CM for every test (including disposing
> 	of the component itself in the tearDown method) but also no
> 	way to use different configs for different tests in the same
> 	TestCase.
> Thoughts?
> Giacomo
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: avalon-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: avalon-dev-help@jakarta.apache.org

Stuart Roebuck                                  stuart.roebuck@adolos.com
Lead Developer                               Java, XML, MacOS X, XP, etc.
ADOLOS                                           <http://www.adolos.com/>

To unsubscribe, e-mail: avalon-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: avalon-dev-help@jakarta.apache.org

View raw message