September 23rd, 2007
One of the places where I am likely to actively use expression trees is testing/mocking.
(I am not the first one to notice this — I saw some post on expression tree asserts, but I lost it).
In my day-to-day development I am using NMock2.
Ayende‘s Rhino Mocks may be more convenient, but I do not like the syntax.
I just can’t read “expect call return” — my mind wants “expect call returns”.
Also, event support in Rhinos is really cryptic.
(I understand that it may be the only stringless way to express it).
So working on C# 3.0 project, I’ve looked into a stringless experience with NMock2.
What I wanted was to pass a method call expression, to change this:
Expect.Once.On(fs) .Method("GetDescendantDirectories") .With(RootPath) .Will(Return.Value(directories));
Expect.Once .That(() => fs.GetDescendantDirectories(RootPath)) .Will(Return.Value(directories));
Fortunately, it was quite easy to do with extension methods.
I have spent more time figuring better fluent syntax than actually writing it.
But the case where expression trees really shine, I think, is in the possibility to do this:
Expect.Exactly(directory.Files.Count) .That(() => access.IsPublicFile(Any.String)) .Will(Return.Value(true));
I can analyze expression tree and find out that Any.String is not “a string”, but “any string”.
It is also easy to imagine Any.String.Matching(“^whatever”) and so on.
I have not tried to implement it, but I feel that it would be simple as well.
Also, while writing the post, I just got an idea — in the world of extenson methods we can do
Expect.Exactly(directory.Files.Count) .That(() => access.IsPublicFile(Any.String)) .Will.Return(true);
without sacrificing extensibility.
“Will” can also be chained if more than one action is needed (however, a delegate would be better for this).
It would be nice to actually add this to NMock2 (as 3.5 branch), but they are using CVS, not SVN.
Also, am I the only one who thinks that SourceForge is slow and has hardly usable (bloated) design?
So if you want the code, you can ask me in comments, but it is primitive indeed.