Unit testing Facade pattern

Published 31.10.2009 01:02 PM by Admin in IOC | Patterns | Testing | Unit testing

The facade pattern is commonly used software engineering design pattern. His purpose is to provide simplified interface to a larger body of code.

It has several good uses:

- Make a software library easier to use and understand, since the facade has convenient methods for common tasks.
- Make code that uses the library more readable, for the same reason.
- Reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system.
- Wrap a poorly-designed collection of APIs with a single well-designed API (as per task needs).

Importance of this Design pattern we cannot underestimate.

In unit testing one of good practice is to put our dependencies in constructor of class. Facade pattern class however cannot have dependencies in constructor because it increase complexity of code.

In this blog post I will show you how to unit test facade pattern.

If I have 2 classes : EmailLogger and DatabaseLogger  and these two classes have same porpoise to Log same data.

These two classes have dependencies on another classes.

I want to have one class that I will call Logger with one method called Log that will be Facade for these two classes.

Class EmailLogger looks like this :

public class EmailLogger:ILogger
{
private readonly IEmailProxy _emailProxy;
public EmailLogger(IEmailProxy emailProxy)
{
_emailProxy = emailProxy;
}
public void Log(string message)
{
if(_emailProxy!=null)
{
_emailProxy.SendEmail(message);
}
else
{
throw new ArgumentNullException("_emailProxy");
}
}
}

 

This class have dependency on another class called EmailProxy and accepts interface IEmailProxy in constructor.

Class DatabaseLogger looks similar to EmailLogger :

 

public class DatabaseLogger:ILogger
{
private readonly IDatabaseMechanism _databaseMechanism;
public DatabaseLogger(IDatabaseMechanism databaseMechanism)
{
_databaseMechanism = databaseMechanism;
}
public void Log(string message)
{
if(_databaseMechanism!=null)
{
_databaseMechanism.SendLogToDatabase(message);
}
else
{
throw new ArgumentNullException("_databaseMechanism");
}
}
}

 

This class have dependency on class called DatabaseMechanism and accepts another interface IDatabaseMechanism in constructor.

And finally we have class called Logger that will be Facade for these two classes .

In this example I will use singleton implementation Unity container and Rhino Mocks.

 

public class Logger:ILogger
{
private readonly ILogger _emailLogger;
private readonly ILogger _databaseLogger;
public Logger()
{
IContainer container = new UnityContainer();
_emailLogger = container.Resolve("EmailLogger");
_databaseLogger = container.Resolve("DatabaseLogger");
}
public void Log(string message)
{
if(_emailLogger!=null)
{
_emailLogger.Log(message);
}
else
{
throw new ArgumentNullException("_emailLogger");
}
if (_databaseLogger != null)
{
_databaseLogger.Log(message);
}
else
{
throw new ArgumentNullException("_databaseLogger");
}
}
}

 

And of course we need to have some registration in container in some BootStraper class :

 

public static class BootStraper
{
public static void SetUp()
{
IContainer container = UnityContainer.Instance();
container.RegisterType();
container.RegisterType();
container.RegisterType("EmailLogger");
container.RegisterType("DatabaseLogger");
}
}

 

Consuming this class is simple :

 

public class Consume
{
public void ConsumeLogger()
{
Bootstraper.SetUp();
ILogger logger=new Logger();
logger.Log("Some message");
}
}

 

Code is simple and understandable and we don’t need to use any container to call this class . If someone reference your dll it can use your code without any container registration or resolve . You just call  method in that class and he not see container calls and deeper logic inside this Facade class.

And finally test is very simple too :

 

[TestClass]
public class LoggerTests
{
private readonly ILogger _emailLogger;
private readonly ILogger _databaseLogger;
private readonly IContainer _container;
public LoggerTests()
{
_container = UnityContainer.Instance();
_emailLogger = MockRepository.GenerateMock();
_databaseLogger = MockRepository.GenerateMock();
_container.RegisterInstance("EmailLogger", _emailLogger);
_container.RegisterInstance("DatabaseLogger", _databaseLogger);
}
[TestMethod]
public void Log_AcceptCorrectArgs_CallsEmailLoggerLog()
{
//arrange
ILogger logger = new Logger();
//act
logger.Log("Something");
ILogger emailLogger = _container.Resolve("EmailLogger");
//assert
emailLogger.AssertWasCalled(x => x.Log("Something"));
}
}

 

We register instance of mock objects EmailLogger and DataBaseLogger in Container and resolve later in test to ensure that correct method of mock object is called.

I hope this will help you in some of your projects.

Currently rated 2.7 by 3 people

  • Currently 2.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

These days everybody are using IOC container so I tried to integrate SL 3 Beta(MIX09) Sample chat application that represent how to work with polling duplex with Unity Ioc container. That sample chat application is available for download on codeplex.

After looking how to integrate Unity with Wcf I have founded few nice examples. All those examples are pretty much same.

To integrate Unity with Wcf we must create UnityServiceHostFactory and in markup of service say that service use that factory.

Polling duplex however has also DuplexServiceFactory. So how I integrate those two factories?

I have created all classes needed for UnityServiceHostFactory in UnityServiceHostFactory.cs file such as UnityServiceHost, UnityInstanceProvider and UnityServiceBehavior.

To make example more interesting I have also create IExample interface to inject this interface in service contructor like this:

public ChatService(IExample example)

        {

            examp = example;

            //Set up a stock update every 5 seconds

            this.stockTimer = new Timer(

                new TimerCallback(StockUpdate),

                null, 0, 5000);

        }

void StockUpdate(object o)

        {

            StockTickerMessage stm = new StockTickerMessage();

            //change this message to use method in interface

 

            stm.stock = "MSFT";

            stm.stock += examp.GetMessage();//calling method from injected interface

            stm.price = new System.Random().Next(20, 50);

            PushToAllClients(stm);

        }

In StockUpdate method in ChatService class in have called method GetMessage from Example class:

class Example : IExample

    {

        public string GetMessage()

        {

            return "Example";

        }

    }

In DuplexServiceFactory I have changed CreateServiceHost to use Unity container.

 protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)

        {

 

            UnityServiceHost host = new UnityServiceHost(serviceType, baseAddresses);

            UnityContainer unity = new UnityContainer();

            host.Container = unity;

 

 

            unity.RegisterType<IExample, Example>();

 

 

      

 

            CustomBinding binding = new CustomBinding(

              new PollingDuplexBindingElement(),

              new BinaryMessageEncodingBindingElement(),

              new HttpTransportBindingElement());

 

            host.Description.Behaviors.Add(new ServiceMetadataBehavior());

            host.AddServiceEndpoint(typeof(IUniversalDuplexContract), binding, "");

            host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

 

            return host;

        }

Now if I run my sample application I get error:

“The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.”

Reason for this is because my Polling duplex class is decorated as singleton class

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

    public abstract class DuplexService : IUniversalDuplexContract

    { 

and ServiceDescription.CreateImplementation and is hard-coded to look for a parameterless constructor.

But I want to make contructor injection so my service class must have contructor with parameter.

I have been remove [ServiceBehavior(InstanceContextMode=InstanceContextMode.SIngle)] and let Unity to return singleton instance of DuplexService class.

So I have put in web config file some code that Unity will use to return Singleton instance of DuplexService.

<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                  Microsoft.Practices.Unity.Configuration" />
<unity>
<containers>
<container>
<types>
<type type="Microsoft.Silverlight.Cdf.Samples.Duplex.IUniversalDuplexContract,ChatWebApp"
mapTo="Microsoft.Silverlight.Cdf.Samples.Chat.ChatService,ChatWebApp"
>
<lifetime type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
    Microsoft.Practices.Unity" />
type>
types>
container>
containers>
unity>

After that I have consumed code from web config in my application.

  UnityServiceHost host = new UnityServiceHost(serviceType, baseAddresses);

            UnityContainer unity = new UnityContainer();

            host.Container = unity;

 

 

            unity.RegisterType<IExample, Example>();

 

 

            UnityConfigurationSection section;

            section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

            section.Containers.Default.Configure(unity);

I have tested this by calling IUniversalDuplexContract cont1 = unity.Resolve() twice and comparing hash of two instances.

Hash was exactly same.That means that  Unity returns singleton instance of ChatService class.

I hope this will help.

Demo project : DuplexWithUnity.rar

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Radenko Zec Blog

Silverlight, C#, WCF, WPF,NET...