Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

DDDD 8 [Fluent Builders and Tests]

Ok this will not be the only post I wrote on this subject as its a pretty big one but I had some good discussions with Udi about this over the weekend. I find that my present way of doing this is pretty cool and of great value to people already using messaging systems without having a big discussion about all of the aspects of testing in messaging based systems (I imagine that would be about 50-60 pages for a cursory overview).

 

In commenting on Messages are Value Objects korkless hit the nail on the head as to why equality comparisons for messages should be overridden to operate with value semantics. When I am testing I can use my fluent interface to build up the message I expect to receive and compare the two of them in a single Assert. I should have been more clear when I said “I can’t see why anyone would use this in their domain”; there is a use for it … just not so much in your domain as in your tests.

 

Since I am fried still but code speaks 1000 words; I am taking a simple test from Mocks are a Code Smell and implementing it here with a fluent builder to illustrate.

 

public void Controller_ShouldRequestAuthentication_When_CardInsertedMessageReceived()  
{
ATMController Controller = New.ATMController.InState(ATMController.States.AwaitingCard);
CardInsertedMessage InsertedMessage = New.CardInserted.ForCard("1111111111111111").WithAccountHolderOf("Greg Young");
controller.ConsumeMessage(InsertedMessage);
List messages = new List(FakeMessageDispatcher.AllMessages());
RequestAuthenticationMessage Expected = New.RequestForAuthentication.ByPinNumberOnly.From(Controller);
Assert.AreEqual(Expected, messages[0]);
}

This allows me to write a very fluent test … as we will see later, we can even refactor this test to be much smaller and more expressive : imagine …

public void Controller_ShouldRequestAuthentication_When_CardInsertedMessageReceived()  
{
When.A(New.ATMController.InState(ATMController.States.AwaitingCard))
.Consumes(
New.CardInserted.ForCard("1111111111111111").WithAccountHolderOf("Greg Young")
)
.Expect.AMessageOf(New.RequestForAuthentication.ByPinNumberOnly.From(Controller));
}

The fact that I am using a fluent builder to define my expectation helps to make my expectations a lot clearer and to avoid having multiple asserts. If later I decide to add a field to the message and the object sets that field away from its default I will also now get a test failure since I am allowing the message to do its own comparison.

 

This is an important pattern to keep in mind not only for messages but also for Value Objects within your domain since as I said before …. Messages are Value Objects.

 

 

One thing I have been playing a lot with lately is changing tests like this to a context based format … just a passing thought.

This entry was posted in DDD, DDDD. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

One Response to DDDD 8 [Fluent Builders and Tests]

  1. error3 says:

    Hi Greg,

    I’ve just finished to read all your DDDD articles. They are very complete.
    I would glad to ask you some questions in private.
    But I did not find your email address.
    Could you send me a mail at error3 AT free.fr

    Thank you very much

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>