Senin, 06 September 2010

Mammoth Extensibility Infrastructure (Plugability and Integration Testing)

Open Architecture


In my project there is an extensibility infrastructure. It makes application possible to load assembly at runtime. Actually my first thought was using MEF, but after done further investigation I found that MEF didn't match with what I needed.

Extensibility Infrastructure


What so special about that library is the ability to intercept its object creation. So I can possibly: Create proxy object of the add-ins or Mock the add-ins when doing integration testing take a look at the ExtensionResolver class for more detail.

The main idea of the extensibility resolver is using IObjectCollectionCreator, so in the implementation it can be override to match what I need.

Proof of Concept


Look at the implementation of the ObservableObjectCreator by assign this object to extension resolver I can get an object support WPF databinding whereas inherrited from INotifyPropertyChanged and all its generic collection property will change to ObservableCollection.

The most interesting one is for Integration Testing. I'm not sure if it is can be done in MEF, but by mammoth extensibility infrastructure I make AssertObjectInterceptor whereas it will inject a AssertCallback to the dummy Add-Ins. so whenever each method of dummy Add-Ins calls by service, AssertCallback will send Assert event, further i can put Assertion on that event handler. Take a look at the test fixture:

AssertCallback assertCallback;
ResponderService target;
bool HasNoError;
ManualResetEvent resetEvent;

[TestInitialize]
public void Initialize()
{
assertCallback = new AssertCallback();
resetEvent = new ManualResetEvent(false);
HasNoError = true;
target = new ResponderService();
//the most inportant thing is here
target.ObjectCreator =
new AssertObjectCreator(assertCallback);
target.Error += (s, e) =>
{ HasNoError = false; resetEvent.Set(); };
}

[TestMethod]
public void WhenServiceRun_ShouldLoginAllServices()
{
bool isLoginCalled = false;
assertCallback.Assert += (s, e) =>
{
if (e.MethodName == MockService.LOGIN_METHOD)
{
isLoginCalled = true;
resetEvent.Set();
}
};

target.Run();
resetEvent.WaitOne();

mock.VerifyAll();
Assert.IsTrue(HasNoError);
Assert.IsTrue(isLoginCalled);
}


and Implementation of the MockService is:


public class MockService : IMessagingService
{
//some code has been cutted for clairity
public static string SEND_MESSAGE_METHOD =
"MockService.SendMessage";
public virtual void SendMessage(
string targetEmail, string message)
{
}
}



That's all, the library a bit far from simplicity (like MEF done with Attribute) but here I win the flexibility.

Happy Codding.