Monday 12 July 2010

Just can't plug this in, baby!

I've just lost about half a day fighting with a stupid StructureMap exception:
StructureMap.Exceptions.StructureMapConfigurationException: StructureMap configuration failures:
Error: 104
Source: Registry: StructureMap.ConfigurationExpression,StructureMap
Type Instance 'bf0f9bf6-304d-4d7b-9cd4-59437e94eb10' (Smart Instance for System.Data.SqlClient.SqlClientFactory) cannot be plugged into type System.Data.Common.DbProviderFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-----------------------------------------------------------------------------------------------------

at StructureMap.Diagnostics.GraphLog.AssertFailures()
at StructureMap.Container.Configure(Action`1 configure)
at StructureMap.ObjectFactory.Configure(Action`1 configure)
My actual code was this:
ObjectFactory.Configure(expr =>
{
expr.For<DbProviderFactory>().Use<SqlClientFactory>();
});


What do you mean by "cannot be plugged in", and why Google can't help me here???

So, a couple of hours later (and with a big help from CThru and Reflector), and I find the StructureMap.Graph.TypeRules.CanBeCast method, which is not just about casting, but says no when, among other things, the concrete type (SqlClientFactory in our case) has no default constructor.

Ok, I can understand. StructureMap doesn't know how to create a concrete instance. How about this:
expr.ForRequestedType<DbProviderFactory>().Use(SqlClientFactory.Instance);
Still no luck:
StructureMap.Exceptions.StructureMapConfigurationException: StructureMap configuration failures:
Error: 104
Source: Registry: StructureMap.ConfigurationExpression,StructureMap
Type Instance '42b890e6-54dc-457e-897a-3e8becc7d0fb' (Object: System.Data.SqlClient.SqlClientFactory) cannot be plugged into type System.Data.Common.DbProviderFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
This is more weird, but a look into the code tells me that we still require the target type to have a default constructor (cause we call the same method). Must be a bug in StructureMap. Too bad, since that would be the most clear and logical solution.

Finally this one worked for me:
expr.ForRequestedType<DbProviderFactory>() .AsSingletons(). TheDefault.Is.ConstructedBy (ctx => SqlClientFactory.Instance);

Have fun!

Monday 5 July 2010

Testing Asp.Net pages with Telerik's JustMock

It is always nice when a competitor publishes a piece of their code. You can always sneak into the comments and, like, look, I'm better! and put a link to your blog where you show your version proudly, and get a massive following.

Guess what, this is what I'm doing right now commenting on the Mehfuz's post. But the main thing I realized reading his post is that this is the perfect example of how using mocks in certain situations can turn testing into a nightmare. The following is not a problem with JustMock, it's a problem with trying to write a unit test involving a complex framework, and isolating parts of it not meant to be isolated.

(Disclaimer: I do understand that the purpose of the original post is not to teach us how to test Asp.Net pages, but to demonstrate the capabilities of JustMock. So, my intent is not to prove that the author is wrong, but rather to take his example as a perfect situation where mock should absolutely not be used.)

So, in order to write the test, we have to
  1. Mock the HttpBrowserCapabilities class and stub a couple of its properties so that it returns something when needed.
  2. Mock the HttpRequest class (of course) and make the mock return our mocked Browser.
  3. Mock the HttpResponse class as well.
  4. Mock the HttpContext class and stub its Request and Response properties (make the getters return our mock instances).
  5. Finally, we are stubbing the Page.RenderControl method, and it's unclear whether we do it to avoid exceptions, or just for fun.
The main purpose is to test whether the Page instance fires all (well, just some) its lifecycle events, and it's done not using mocks but rather adding event handlers (since we already have our Page instance).

Why do we have to mock all these classes? Why do we have to fire up Reflector and dig into the Framework source in order to make our test pass? Because we have this idea that unit testing means testing a particular class in isolation. Somehow all calculator examples left us with an idea that "unit" == "class".

Now, let's back off a bit and consider this: we are testing a high-level ProcessRequest method, which does a lot of lower-level calls to various classes, which are tightly coupled with each other. So, I think it's logical to say that our "unit" is a good part of the System.Web assembly. With that assumption, everything becomes simple: we don't test just our Page instance, we test the whole unit. Assuming we are the developers of the framework, we can also test the lower level methods which have less dependencies, so that we can mock them more easily.

Back to our integration test, here's what it looks like when we use Ivonna. I have omitted all asserts for clarity; instead, we just write messages to the console, as we would in an exploratory test:
[Test]
public void TestingPageEvents()
{
 var session = new TestSession();
 var request = new WebRequest("Default.aspx");
 request.EventHandlers.Page_Init = 
             (sender, e) => Console.WriteLine("Init fired");
 request.EventHandlers.Page_Load = 
             (sender, e) => Console.WriteLine("Load fired");
 session.ProcessRequest(request);
}


This code executes a test against a "real" Web page, with a "real" HttpContext and other necessary objects, so it gives us much more valuable information about the behavior of our system in "real world" situations.

Check out a fresh version of Ivonna here.

Friday 18 June 2010

C-eeing Thru Your Code


Ladies and gentlemen, let me introduce you to this exciting library, CThru. (I planned to add several jokes here, but changed my mind). This is an open source AOP framework built on top of Typemock Isolator. Recently I added several improvements to the built-in aspects, and thought I might write a blog post about it.

CThru requires Typemock Isolator to be installed on the target box, so you probably want to use it in your test projects. CThru does not require you to modify the original code, nor the compiled binaries, so you're free to use it on, say, BCL libraries (except for mscorlib). It works by intercepting method calls and add or change their behavior. Each aspect is responsible for deciding which calls to intercept by implementing the ShouldIntercept method. You can make a decision based on the target instance, class name, or method name. For example, you could apply it to all implementors of a particular interface, or for all types in a particular namespace.

In order to make it work, you add all necessary aspects by calling CThruEngine.AddAspect(), then call CThruEngine.StartListening(). The cleanup is done by calling CThruEngine.StopListeningAndReset().

So, how do you write your own aspect? First, you inherit from the abstract Aspect class, and implement the ShouldIntercept method. As I said before, it determines the condition for which the aspect is applied. To add specific behavior, you should override the MethodBehavior or ConstructorBehavior methods. By default, your code is run before the actual method is invoked. You can also skip the original method, return custom value, or throw an exception by manipulating the properties of the DuringCallbackEventArgs valued argument. If you want to add some behavior after the original method is invoked, you can execute the Aspect.CallOriginalMethod method (don't forget to set e.MethodBehavior = MethodBehaviors.SkipActualMethod so that it isn't called twice).

There are aspects that are generic in nature: the behavior is the same, but they are applied in different situation, so it doesn't make sense to hardcode the ShouldIntercept method. For example, the Stub aspect just ignores the method call, but which call it ignores should be determined by the code that uses the aspect. So, there's a convenient base class called "CommonAspect". It makes it possible to pass the intercepting decision in the constructor argument. For example, if you want to ignore all methods with names starting with "My", you write:
CThruEngine.AddAspect(new Stub(info => info.MethodName.StartsWith("My")));
That said, let's review some of the built-in aspects:
  • SkipAllByTypeName -- very simple aspect, designed to illustrate how aspects should be written. Skips all method calls of classes that contain the specified string in their names.
  • MissingMethodAspect -- implements Ruby-like behavior in VB.Net (when you try and execute a non-existent method, it invokes the method called "method-missing" instead).
  • TraceAspect -- traces all intercepted calls to the console (or the supplied TextWriter instance), optionally with the stack trace.
  • TraceResultAspect -- same but traces the results as well. Due to the CThru limitation, all calls invoked by the traced call are not traced (unlike with TraceAspect).
  • DebugAspect -- if you have attached the debugger, it pauses the execution before calling the intercepted method. Very useful for investigating the state of the system at a particular point, when you don't have access to the code at that point.
  • Stub -- just ignore the call and return null. ToDo: implement returning a custom value.
Several projects that are built on top of, or developed using, CThru:
  • SilverUnit, a framework for testing Silverlight applications. Bundled with CThru.
  • Balder. Managed 2D and 3D graphics engine, targetting Silverlight, Xna and OpenGL.
  • Ivonna, an Asp.Net unit and integration testing tool.

So, whether you just need some exploratory testing, or building a domain-specific test framework, CThru can save you a lot of effort.

Monday 14 June 2010

On structuring your tests


The ideas presented here are nothing new; however, a recent discussion with Dror Helper made me want to state my views on this subject (and make the whole world agree with me, whatever it takes), because to be honest, despite my best efforts in meditation, when I see a class called "MyClassTester" it makes me.. wanna start a holy war nervous.

The idea is, if you do TDD, you don't start with a class, because if you do, you already have some design before you have written any tests. So, you start with a user story. Ant let it be a Web app, to be more concrete. Here it goes:
When a user fills the registration form correctly and hits the "Register" button, several things happen:
  • she becomes, in some sense, "registered" in the system;
  • an email is sent, containing the confirmation link;
  • she's redirected to a particular screen.
Now, if I were to start writing unit tests for a particular class, which class would it be? The specs say nothing about classes or such. So, first, I decide that it's going to be an MVC app, like all the cool guys doing these days. And I'm going to start with the most exciting thing: my controller. So, I'm creating a class called AccountControllerTester or something. Next, I have to write a test, so I meditate over the requirements, and here's what I think:
  • "Registered" is kinda vague, but let's do it with the built-in Membership system. I'll inject this service into my controller, mock the service in my test and verify the call to it.
  • Email is easy. A service again, I'll write it later (after the lunch), let's use an interface for the moment.
  • Redirection is just return View(".."). Easy to test.
So you end up with either one test with three asserts (which is a bad practice), or three test methods related to one particular feature. What makes it a mess is that you're going to add more tests: related to input validation, and to the other features that are handled by this controller: password change and retrieval, email confirmation etc. For every action method, you can have 5-10 tests. On the other hand, the actual confirmation email sending belongs to a different class, so you probably put the test there, together with other email-related tests.

You see, one big problem is that each test class becomes huge. But what's more important, it is hard to tell what your system does. One purpose of tests is documentation, and it should be readable for outsiders. If I am to figure out the behavior of the system in the registration process, where should I look? How do I know that part of it is in the AccountControllerTests, and another part is in the EmailServiceTests?

And still another problem is that you just wrote a lot of code, but made zero business value with it. I mean, I can't register at your site yet! And won't be able until you write all the pieces and connect them together (for which you probably should write an integration test).

To summarize, what you get with this approach is:
  • premature, rather than test-driven, design;
  • potentially brittle tests (since they are coupled to your classes, you can't refactor easily);
  • huge test classes;
  • documenting your classes rather than your system;
  • no clear relationship between the specs and your tests;
  • no business value until you have all the pieces.

There's a better way

Now, let's do it another way. Let's create a folder called Membership, and inside it a folder called "Registration". We're testing the case when we submit valid registration data, so let's make a test class called "IfSubmittedValidRegistrationData". The test methods will be called "ShouldSendConfirmationEmail" etc, so the test output will show something like,
WhenSubmittedValidRegistrationData.ShouldSendConfirmationEmail -- passed.
This is quite close to documenting your system!

Now, you can still write it as a unit test for your controller, if you prefer, but I suggest you start with integration tests. I use Ivonna for testing, and it makes it a lot easier: my "integration" is only server-side. In addition, I can use several built-in CThru aspects, like EmailSpy, and I can use a lightweight in-memory database. I initialize the posted values (Arrange) and execute the request (Act) in the FixtureSetup method, and all my test methods are one or two lines of code where I verify the results.
  • UserShouldBeRegistered -- I just check it via the MembershipAPI.
  • ShouldSendConfirmationEmail-- I use EmailSpy that prevents the message from being sent, and saves it for further investigation, so that I can verify that it contains the confirmation link, is being sent to the correct address etc.
  • ShouldRedirectToTheWelcomeScreen -- check the Ivonna.Framework.WebResponse.RedirectLocation property.
Now I can go the full Red-Green-Refactor way. I stuff all the code into my action method until all my tests pass. At this moment my system actually works: I can register a user! But my code is ugly: it is a quick-and-dirty solution written just in order to make my tests pass. I want to make it better. So I refactor it.

It's at the refactoring phase that unit tests can provide a big value. Yes we all know that unit testing can lead us to a much better design. But sometimes it is enough to do it mentally. For example, "how would I unit test my controller"? Oh yes, I should refactor the email-related code into a separate class, and do dependency injection. Probably extract an interface like IMessagingService and implement it as EmailService. Whatever. But I actually write a unit test only if I can think of a good name for it. EmailServiceTester totally won't do. TheConfirmationMessageShouldBeActuallySentByEmail is more like it (and the corresponding unit test for the controller is ShouldSendTheConfirmationMessage -- note that it doesn't mention "email"). But in this particular case, it's probably not worth it.

There is another situation when we have a particular feature that produces some output depending on various inputs, and it's not a yes/no situation, like in the previous case. Take searching, for example. You start with an integration test, like before. And make it work. For one of several search form parameters, you know that the search produces the correct results that appear in a grid on the search results page. It would be wasteful to write integration test for every search parameter. So, assume we already have it refactored into several units (note that I don't say "classes"): SearchParamsReader (this is actually the MVC Binder), TheThingThatGivesUsSearchResultsDependingOnTheSearchParams, and SearchResultsWriter (the one responsible for displaying the results). You make three subfolders in your Searching folder (which already contains the integration test), each responsible for the corresponding piece of functionality. Actually, it's probably worth it to make just one subfolder and test TheThingThat.. Again, you don't put everything for testing TheThing.. into one huge class, but you create several classes: SearchByKeyword, SearchByMinMaxPrice etc. This is unit, not integration, testing, and yet it corresponds to user requirements and documents the system behavior. I could refactor TheThing.. into several classes, I could rename it, and the tests won't break.

Here's the recipe for happiness

  1. Make a folder corresponding to a feature, then a subfolder for a sub-feature etc, until you have a concrete action, like registration or search, or maybe a concrete context.
  2. Inside, create a fixture for each combination of context + action (like "submitting a duplicate username") and name it accordingly (WhenSubmittedExistingUsername).
  3. Put all preparation into the FixtureSetup method. You want it to be readable, so refactor all the nasty details into private methods and move them to the end.
  4. Each check should go to a separate Test method. Name them so that they match the requirements.
  5. More granular tests, if you need them, should go to subfolders.
  6. If you can't think of a decent test name (something that doesn't use the class/method names), it's probably not worth writing (but might be useful for driving your design).

Tuesday 4 May 2010

Fixing the namespace problem in VB.Net XML literals

Recently I tried to parse a Web page output using the shiny VB.Net syntax. I had an XElement representing a dropdown, and tried to count the options using something like
purposeChooser.
Although I could clearly see that there is one child "option" element, it kept returning a zero. Then I realized that there might be some namespace trouble. Indeed, the top html tag had some namespace attached, and, naturally, it was inherited by the select (and the option) element. However, it didn't include a prefix, so how do I tell what to look for? The answer is, you can import an XML namespace just like you can a "regular" one, putting this at the top of your code:
Imports
And now this expression
purposeChooser..Count
returns 1, as expected.

Saturday 17 April 2010

Using the EditorFor method in MVC2 to display child collections

I was very excited when I discovered the new DisplayFor and EditorFor extensions in the new MVC release. In fact, they look even better than the similar MVCContrib features.

The only problem is that when I tried to render a child collection, it displayed nothing. This is kinda weird, because when your model is a collection, it shows just fine. However, as this post explains, anything complex enough (that is, not convertible to a string) is just filtered out.

It turned out that it could be fixed relatively easily. You have to override the default Object template and fix the logic. Just create a view called Object.ascx in your Views/Shared/EditorTemplates folder, copy the default template from here, and modify the filtering logic. Took me a while, since I had to convert it to VB.Net. Here's the result:

<%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl" %>
<%@ Import Namespace="System.Globalization"%>
<%@ Import Namespace="System.Linq" %>

<% If (ViewData.ModelMetadata.Model Is Nothing) Then%>
<%=ViewData.ModelMetadata.NullDisplayText%>
<% Else%>
<% If (ViewData.TemplateInfo.TemplateDepth > 3) Then%>
<%=Me.ViewData.ModelMetadata.SimpleDisplayText%>
<% Else%>
<% Dim props = From pm In Me.ViewData.ModelMetadata.Properties Where pm.ShowForEdit AndAlso Not ViewData.TemplateInfo.Visited(pm) For Each prop In props If prop.HideSurroundingHtml Then%>
<%= Html.Editor(prop.PropertyName) %>
<% Else Dim str As String = Html.Label(prop.PropertyName).ToHtmlString If Not String.IsNullOrEmpty(str) Then%>
<%= Html.Label(prop.PropertyName) %>

<% End If%>

<%= Html.Editor(prop.PropertyName) %>
<%= Html.ValidationMessage(prop.PropertyName, "*") %>

<% End If%>


<%Next%>
<% End If%>
<% End If%>

Don't forget to check the line related to TemplateDepth. Originally, it makes a shallow copy: everything with the depth>1 is just displayed as a simple string. You might want to make this number greater, or remove the check entirely.

Friday 9 April 2010

Using the latest NHibernate features in your VB.Net code.

No doubt you have tried the newest LINQ-to-NHibernate bits in your VB.Net application already. If you have gotten past retrieving all records from a specific table, you might been getting an exception similar to this one:

System.Exception: Unrecognised method call in epression CompareString(aUser.Name, value(Web.Controllers.Membership.AccountMembershipService+_Closure$__1).$VB$Local_userName, False)
at NHibernate.Impl.ExpressionProcessor.FindMemberExpression(Expression expression) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 170
at NHibernate.Impl.ExpressionProcessor.ProcessSimpleExpression(BinaryExpression be) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 295
at NHibernate.Impl.ExpressionProcessor.ProcessBinaryExpression(BinaryExpression expression) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 358
at NHibernate.Impl.ExpressionProcessor.ProcessExpression(Expression expression) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 388
at NHibernate.Impl.ExpressionProcessor.ProcessLambdaExpression(LambdaExpression expression) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 395
at NHibernate.Impl.ExpressionProcessor.ProcessExpression[T](Expression`1 expression) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 406
at NHibernate.Criterion.QueryOver`2.Add(Expression`1 expression) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Criterion\QueryOver.cs:line 568
at NHibernate.Criterion.QueryOver`2.Where(Expression`1 expression) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Criterion\QueryOver.cs:line 248
at NHibernate.Criterion.QueryOver`2.NHibernate.IQueryOver.Where(Expression`1 expression) in f:\Разные штуки\Visual Studio 2008\Projects\OpenSource\NHibernate\nhibernate\src\NHibernate\Criterion\QueryOver.cs:line 619

The code I have is quite innocent:
Return _session.QueryOver(Of User).Where(_
   Function(aUser) aUser.Name = userName).List().First

It returns the first instance of the User class that matches the Name property. The problem is that the VB compiler transforms the lambda into something like
(CompareString(aUser.Name, value(Web.Controllers.Membership.AccountMembershipService+_Closure$__1).$VB$Local_userName, False) = 0)

Now, CompareString is a shared method of the Microsoft.VisualBasic.CompilerServices.Operators class, which is probably not something the NHibernate developers expected to appear in a lambda. Time for a patch. A quick fix is to add the following piece of code in the beginning of the NHibernate.Impl.ExpressionProcessor.ProcessSimpleExpression method:

if (be.Left.NodeType == ExpressionType.Call) {
   var left = (MethodCallExpression) be.Left;
   if (left.Method.Name == "CompareString") {
      return ProcessSimpleExpression(Expression.Equal(left.Arguments[0], left.Arguments[1]));
   }
}

Actually, the CompareString method has 3 arguments. The third one, when set to false, signifies the literal comparison, while being set to true means textual (case insensitive) comparison. So, if you use the LIKE operator, you might want to check for left.Arguments[2].

Sunday 21 February 2010

Ivonna 2.1 is out

Finally, the next release of Ivonna is out! You can read more about this release here. For those of you unfamiliar with Ivonna, it is server-side Asp.Net unit and integration testing tool I develop in partnership with TypeMock.

Thursday 28 January 2010

Fixing the " 'Telerik.Web.UI.GridInsertionObject' does not contain a property with the name" problem

Telerik's RadGrid has a handy possibility to insert a new object. Works fine with DataTables, but since I sure prefer using ObjectDataSources, sometimes I get the abovementioned exception when clicking the Insert button whenever the grid is empty.

The problem is, the grid can't figure out the type of the new record when it doesn't have any records yet. This is sorta silly, since it is bound to an ObjectDataSource object and (theoretically) could get the class name from it. Anyway, it just creates an instance of Telerik.Web.UI.GridInsertionObject and then complains that it can't do the databinding.

There are tons of solutions out there, even provided by the Telerik team, and they typically involve a lot of manual labour. Typically you would create an object yourself or provide some Dictionary with all properties initialized etc. Not exactly a DRY style of work.

My solution is.. just return a generic List rather than an Enumerable for the Select method of your ObjectDataSource. For example, this
Return From product In Me.FetchAll Where product.CategoryId = categoryId
will give an exception when trying to add a record. Change it to
Return (From product In Me.FetchAll Where product.CategoryId = categoryId).ToList()
and you'll be fine.