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

Radenko Zec Blog

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