Unit testing Facade pattern
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<ILogger>("EmailLogger"); _databaseLogger = container.Resolve<ILogger>("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<IEmailProxy,EmailProxy>(); container.RegisterType<IDatabaseMechanism,DatabaseMechanism>(); container.RegisterType<ILogger,EmailLogger>("EmailLogger"); container.RegisterType<ILogger,DatabaseLogger>("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<ILogger>(); _databaseLogger = MockRepository.GenerateMock<ILogger>(); _container.RegisterInstance<ILogger>("EmailLogger", _emailLogger); _container.RegisterInstance<ILogger>("DatabaseLogger", _databaseLogger); } [TestMethod] public void Log_AcceptCorrectArgs_CallsEmailLoggerLog() { //arrange ILogger logger = new Logger(); //act logger.Log("Something"); ILogger emailLogger = _container.Resolve<ILogger>("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.
Nikola Malovic
October 30, 2009 at 10:51 am (15 years ago)First of all, nice blog post!
I have couple of (lengthy) comments\questions:
1. I am not exactly sure this example is Façade pattern at all.
If you take the Wikipedia definition enlisting Façade advantages (as the list given at the beginning of the post), you would see that each one of them points to a use case where you have a class\API which has “too many features” so you put a Façade on top of it to show only the members your code care for. In case of logger façade would be MyLogger class which would have a subset of BigLogger API. In other words, Façade is more of a 1-1 relationship between façade and “original” class. That’s your example is not Façade IMHO (you have 1->2 relation in it)
Adapter pattern http://tinyurl.com/adapterex is very similar to Façade in that 1 -1 sense but it requires existence of third class which contracts the behaviors required by system consuming the foreign APIs. You do have ILogger interface, but all of your classes are implementing it – not adapting to it so I guess this is not adapter too.
Gateway design pattern on other hand (as described http://martinfowler.com/eaaCatalog/gateway.html) is usually explained very much like in your example (http://tinyurl.com/gatewayex), where one class behaves as a single entry point to many classes encapsulating mainly its initialization complexity and exposing one API which calls get delegated down to the encapsulated classes. In your example Logger is gateway for EmailLogger and DatabaseLogger (which in this example share the same interface as Logger – not the typical Gateway use case). Gateway is therefore (at least in my head) like “1 – n Façade”.(“EmailLogger”)
2. We already discuss about it on my blog (http://tinyurl.com/saynotosl), but do you really think having this extra class etc is REALLY simpler than simple using the ctor injection +container.Resolve
3. In your Logger class you throw ArgumentNullException() when _emailLogger and _databaseLogger are null.
Related to that:
a) In which scenario they can be null? AFAIK, Unity throws an exception when there’s not mapping and explicitly mapping null to ILogger is not possible AFAIK
b) IMHO, ArgumentNullException() should be used in cases when outer code injects a null value to a class (e.g. method accepting reference type invoked with null instance) which is here not the case.
I tend to use InvalidOperationException for cases when a class was in “invalid state” to perform its activities which to me looks like the use case you have.
admin
October 30, 2009 at 4:24 pm (15 years ago)You forget two most important uses Facade pattern :
– 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.
Facade pattern can have 1-> many relation. See http://www.dofactory.com/patterns/patternfacade.aspx#_self1
In first example on this site you see that it can be 1->many.
public void MethodA()
{
Console.WriteLine("\nMethodA() —- ");
_one.MethodOne();
_two.MethodTwo();
_four.MethodFour();
}
For your third point you are completely right but sometimes I want to handle error by myself and not leaving Unity to throw exception for me .
That code is however irrelevant to this post.
Nikola Malovic
October 31, 2009 at 9:03 am (15 years ago)I didn’t forget, just didn’t find strong case for your example there 🙂
– Make a software library easier to use and understand, since the facade has convenient methods for common tasks.
Your Logger, EmailLogger and DatabaseLogger inherit the same interface and thus the same API. Logger is NOT at all more convinient then Email and Database loggers
– Make code that uses the library more readable, for the same reason.
This presumes (IMHO) external library (what’s the point of facading your own code – one could just go and adapt it to be the facade) which is not the case in your example.
As for the dotfactory, I disagree with their 1-n example becuase it violates the diferences between Facade, Adapter, Gateway, Mediator, etc patterns (they all “look the same”) but that is just how I “feel” those patterns and that is the first time I see 1-n example. The problem in general with that site is that it is focused only on GoF patterns and completlly ignoring the Fowler PoEAA (where Gateway is detailed). I am not sure if they would cover PoEAA patterns if their examples (including the Facade one) would change or not. 🙂
Even I would agree with that example, you see that it contains external subsystem which just restate my previous statement that Facade has sense only on top of the “external library”
I know that the third point is irelevant to blog post, but I was just currious how come you avoided having try-catch block and check for null… Never mind that 🙂
At the end, I don’t clame my oppinions are correct and your example is wrong. It is just my oppinion base don how I feel those patterns which I wanted to share with you… It is totally up to anyone reading your blog post to agree with them or categorize them under the BS category (probable result) 🙂
Keep up good blog posting!
Nikola
admin
October 31, 2009 at 10:15 am (15 years ago)– Make a software library easier to use and understand, since the facade has convenient methods for common tasks.
Logger, EmailLogger and DatabaseLogger inherit same interface in this blog example but they don’t need to inherit same interface.
This is just blog post quick example. They can have completely different interfaces.
– Make code that uses the library more readable, for the same reason.
Point of facading your own code is : "You always need to think that your code must be easier to consume and understand by other developers and be more readable.
Not all developers are experienced as you are.
I think that you are always looking for better architecture and easier maintenance of code but you don’t think at all who will use your code."
As for the dotfactory similar example is in book C# 3.0 Design Patterns by Judith Bishop and in book Design patterns elements of reusable OO software by GOF .
If you don’t know what Facade pattern is don’t comment where is clever to use it and where is not and call someone blog post bullshit…
Nikola Malovic
October 31, 2009 at 11:08 am (15 years ago)Hey Radenko,
I think you really missread my comment and if you read it again I’m sure you would see that I didn’t say that your blog post is BS but on the contrary I was making a joke that MY OPPINIONS could be categorized as BS by some people reading your blog post. One more time: It was a joke on my own account – totally not related to your blog post – read it again. I really had only good intentions with my comment so it must be either mine or yours bad english and\or haste in your reading\ my writting to be accounted for this missunderstanding.
I’m glad that you know so well what a Facade is and if it would make you happy I would agree that your blog post is the perfect example of what Facade is. For me those patterns are more principles then laws written in the stone. Anyhow, once you would have time do check out the PoEAA book and I guess\hope my oppions would make more sense to you
I am really sorry that you are taking this (honestlly friendly) discussion so wrong, so I’ll stop commenting on your blog posts.. No need for harsh words and statements from anyone regarding computers
So long,
Nikola
admin
October 31, 2009 at 11:23 am (15 years ago)Oh sorry 🙂 I have misunderstand you sentence.I have not read it carefully and my English is not that good. My apologies.
Every opinion is important and I hope someone will surely learn something from our discussion.
You can freely comment on my blog at any time. It is always good to learn something and realize your mistakes.
And hope I can comment some your blog posts too in the future 🙂