Thursday, June 25, 2009

TDD, Xaf, Typemock and eXpand

If you do not know about TypeMock see some cool video tutorials here.
TDD is an software design approach that states:

In order to design your software from the correct angle and don’t get lost in the info you have first write down a test that describes a behavior and then by using tools like ReSharper to actually create the “at most as code as required to make that test past”

There is an excellent video from Gary and Oliver on how to TDD with Xaf. These guys know a lot but you have to analyze each word they say to get the real power out of it. Nice work guys!! and we love to see more videos like that but going deeper onto the “software design” stuff.

Test Driven Development Techniques

Now that I am sure that you know what is TDD is I am going to saw you the following

How do I test a viewController?

Gary and Oliver state that you should refactor your logic out of the controller. But also you can leave it there as well.
Suppose you have a case like : I want to create an abstract controller using BaseObject as a type argument that will implement the following functionality: When a user click on a row of a web list view of objects that belong to “directly edit group” then it should go directly to its equivalent detail view but in edit mode

lets write our test for that behavior

[Test]
public void Test_That_When_A_DetaiView_IsActivated_The_ViewEditMode_Property_Equals_Edit_FirstAttempt()
{
    //setup preconditions
    var viewController1 = new DomainObject1ViewEditModeController();
    viewController1.SetView(new DetailView(new DictionaryNode(""),new ObjectSpace(new UnitOfWork(),XafTypesInfo.Instance),
                                           null, null, true  ));
    viewController1.Active.Clear();

    //if we llok at viewcontroller source code we see that Onactivated is called when Active has change. So here we call OnActivated method
    viewController1.Active[""] = true;

    //setup assertions
    Assert.AreEqual(ViewType.DetailView, viewController1.TargetViewType);
    Assert.AreEqual(ViewEditMode.Edit,((DetailView)viewController1.View).ViewEditMode);

}

ugly code eh? what do you think? I think someone needs to think a “little“ in order to write this!!

now that we have define our bahaviour lets implement it.

public partial class DomainObject1ViewEditModeController : ViewEditModeController<DomainObject1>
{
    public DomainObject1ViewEditModeController()
    {
        InitializeComponent();
        RegisterActions(components);
    }
}

public abstract class ViewEditModeController<Target> : ViewController where Target:BaseObject
{
    protected ViewEditModeController()
    {
        TargetViewType=ViewType.DetailView;
        TargetObjectType = typeof (Target);
    }

    protected override void OnActivated()
    {
        base.OnActivated();
        ((DetailView) View).ViewEditMode=ViewEditMode.Edit;
    }
}

DomainObject1 will now have the expected behaviour. (of course you could implement that behaviour differently I am just doing a TDD,Typemock example here). 

Since the behavior does not change for different DomainObjects, I mean that for testing another object like DomainObject2 we would have to write the same code exactly. It would be very nicer if we could test directly the ViewEditModeController.

But how can we test an abstract class? How can we initialize?

We can use TypeMock Isolator for that. The code bellow I think is self describing

[Test]
public void Test_That_When_A_DetaiView_IsActivated_The_ViewEditMode_Property_Equals_Edit()
{
    //create fake instance of controller
    var controller = Isolate.Fake.Instance<ViewEditModeController<DomainObject1>>(Members.CallOriginal);
    //create fake instance of detailview
    var detailView = Isolate.Fake.Instance<DetailView>();
    Isolate.WhenCalled(() => controller.View).WillReturn(detailView);

    controller.Active.Clear(); 

    controller.Active[""] = true;

    //setup assertions
    Assert.AreEqual(ViewType.DetailView, controller.TargetViewType);
    Assert.AreEqual(ViewEditMode.Edit,((DetailView)controller.View).ViewEditMode);

}

is this code more elegant or what?

Download Sources

For this post I am using MbUnit, TestDriven.Net 

ps: TypeMock has provided an open source license with all features of commercial product for all contributors of eXpand. Also there is a free community version avaliable here

oops wrong again: It's not just for contributors. Anyone who downloads the source and wants to run the tests can get this license as well. The license limits it for non commercial use

thnks TypeMock

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

0 comments:

Post a Comment