Navigation

RSS 2.0 New Entries Syndication Feed Atom 0.3 New Entries Syndication Feed

Show blog menu v

 

General

Use it

Documentation

Support

Sibling projects

RIFE powered

Valid XHTML 1.0 Transitional

Valid CSS!

Blogs : Archives

avatar
< RIFE on java.net frontpage again   Tiger search key shortcut >
Testing web application failures when using Jetty as a decorator

Marty and Mike blog about using Jetty as a test decorator. As they say, this is very useful and we we have been testing all the features of the RIFE web application framework like this automatically inside a real servlet container for years. The nice thing is that each unittest really is run in isolation and that you know a new context is setup everytime. Also, since RIFE supports being integrated both through a gate filter as through a gate servlet, we wrote a custom testsuite integrator that registers each test method once for a 'servlet' test and once for a 'filter' test.

Something we had initially trouble with is how to actually test failing code. You know, ensure that certain exceptions get thrown in certain conditions. We found a nice solution that might help you guys. Jetty logs everything through the org.mortbay.util.Log class, and allows you to register your own LogSink implementations which are able to collect what is going on.

This is the LogSink we wrote for collection internal exceptions:

public class CollectingLogSink implements LogSink
{
    private Stack    mLog = null;
    
    public Stack getLog()
    {
        return mLog;
    }
    
    public void start()
    throws Exception
    {
        mLog = new Stack();
    }
    
    public void stop()
    throws InterruptedException
    {
        mLog = null;
    }
    
    public boolean isStarted()
    {
        return mLog != null;
    }
    
    public void log(String tag, Object message, Frame frame, long time)
    {
        mLog.push(message);
    }
    
    public void setOptions(String options)
    {
    }
    
    public String getOptions()
    {
        return "";
    }
    
    public void log(String formattedLog)
    {
        mLog.push(formattedLog);
    }
    
    public Throwable getInternalException()
    {
        Object last_entry = getLogSink().getLog().peek();
        if (!(last_entry instanceof Code.LogMsg))
        {
            return null;
        }

        return ((Code.LogMsg)last_entry).getThrowable();
    }
}

You're now able to put this in a testsuite base class (this doesn't work in a decorator since you need access to the logsink instance from inside your tests):

...
private CollectingLogSink  mLogSink = null;

protected CollectingLogSink getLogSink()
{
    return mLogSink;
}

...

To register the LogSink with Jetty you add this to your setup() method:

// Disable debug output
Log.instance().disableLog();
mLogSink = new CollectingLogSink();
mLogSink.start();
Log.instance().add(mLogSink);

After that you're able to write code like this in your tests, for instance:

public void testMyStuff()
throws Exception
{
    // setup a HttpUnit conversation
    WebConversation conversation = new WebConversation();
    WebRequest request = new PostMethodWebRequest("http://localhost:8181/submissions/valid");
    
    try
    {
        // perform your request with HttpUnit for instance:
        conversation.getResponse(request);
        
        // test that the execution failed and that an exception was triggered
        assertTrue(false);
    }
    // catch the exception
    catch (HttpInternalErrorException e)
    {
        // get the exception of your application and test it's type
        Throwable e2 = getLogSink().getInternalException();
        assertTrue(e2 instanceof SubmissionUnknownException);

        // analyze the data of your exception
        SubmissionUnknownException e3 = (SubmissionUnknownException)e3;
        assertEquals("unknown", e3.getSubmissionName());
        assertEquals(e3.getDeclarationName(), "element/submission/valid.xml");
    }
}

So, I have this is useful for someone, it has already served us well in many occasions.

posted by Geert Bevin in Java on Jul 12, 2004 9:10 AM : 0 comments [permalink]
 

Comments

Add a new comment

:) ;)
=) :-)
:'( :(
:/ :D
:| :p
:o 8)
Your email address will not be displayed at anytime on any page.
Only provide your email address if you'd like updates on this entry
and it's comments by email.
Please answer this simple math question:
14 + 11 = 
 
 
  

Manage subscription

Remove email:
 

< RIFE on java.net frontpage again   Tiger search key shortcut >
 
 
 
Google
rifers.org web