Dashboard > MbUnit > ... > MbUnit Home > TestDecoratorOverview
  MbUnit Log In View a printable version of the current page.  
  TestDecoratorOverview
Added by Jonathan de Halleux, last edited by Jonathan de Halleux on Jul 02, 2005  (view change)
Labels: 
(None)

When you are tagging a method with ExpectedExceptionAttribute, you are actually "decorating it" with a wrapper that will intercept exceptions and check that they are of the right type.

Unable to find source-code formatter for language: cs. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Test()
{
   throw new ArgumentNullException();
}

The [ExceptedExceptionAttribute] acts as a [DynamicProxy] around the Test invokation, doing some pre and post actions. Test decorators can also be applied directly to the fixture, in that case, they are applied to all the tests produced by the fixture. The example below shows how to make a fixture 'ignored':

Unable to find source-code formatter for language: cs. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
[TestFixture] 
[Ignore]
public class MyFixture
{
   ...
}

Implementation

All decorator inherit from the [DecoratorPatternAttribute] attribute and have to implement 1 method:

Unable to find source-code formatter for language: cs. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
public abstract IRunInvoker GetInvoker(IRunInvoker wrapper);

In this method, wrapper is the [IRunInvoker] instance that represents the method call. The GetInvoker is used to install additional funcitonalities. Therefore, implementing a custom decorator usually involves implementing a custom [IRunInvoker]. MbUnit also provides a base class for such [IRunInvoker] implementations: [DecoratorRunInvoker].

Tutorial sample

This sample shows how a decorator can be used to change the current Culture and restore it afterwards. At first, we create a new [CustomAttribute] that inherits from [DecoratorPatternAttribute]. In the GetInvoker of this method, we return a [IRunInvoker] instance that does the job, [ChangeCultureRunInvoker].

ChangeCultureRunInvoker.Execute is where the current culture is substituted and restored.

Unable to find source-code formatter for language: cs. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
using System;
using System.Collections;
using System.Threading; 
using System.Globalization;  

using MbUnit.Core.Invokers;
using MbUnit.Core.Framework;

namespace MbUnit.Demo
{
    [AttributeUsage(AttributeTargets.Method,AllowMultiple =false,Inherited = true)]
    public class ChangeCultureAttribute : DecoratorPatternAttribute
    {
        private string name;
        public ChangeCultureAttribute(string name)
        {
            if (name == null)
                throw new ArgumentNullException("null");
            this.name = name;
        }  

        public override IRunInvoker GetInvoker(IRunInvoker wrapped)
        {
             ChangeCultureRunInvoker invoker = 
               new ChangeCultureRunInvoker(this.name,wrapped);
            return invoker;
        } 

        internal class ChangeCultureRunInvoker : DecoratorRunInvoker
        {
           private string cultureName;
           public ChangeCultureRunInvoker(string cultureName, IRunInvoker invoker)
               :base(invoker)
           {
               this.cultureName = cultureName;
           }  

           public override Object Execute(
                object o, 
                IList args)
            {
                CultureInfo culture = null;  
                try
                {
                    culture = Thread.CurrentThread.CurrentCulture;
                    Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureName);  
                    return this.Invoker.Execute(o, args);
                }
                finally
                {
                    if (culture!=null)
                        Thread.CurrentThread.CurrentCulture = culture;
                }
            }
        }
    }
}

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.9 Build:#527 Sep 07, 2006) - Bug/feature request - Contact Administrators