Tuesday 28 April 2015

Is a test that tests intent a valid test?

Is it valid to test intent rather than function?
1:  container.Register(  
2:     Classes  
3:        .FromThisAssembly()  
4:        .BasedOn<Controller>()  
5:        .WithServiceBase()  
6:        .WithServiceSelf()  
7:        .LifestylePerWebRequest()  
8:  );  
This code registers MVC controllers with a Castle Windsor container with the following intent:
  1. That all controllers can be resolved using their base type (Controller);
  2. That a specific controller can be resolved by name (CustomerController);
  3. That resolved components lifetime will be linked to the lifetime of the web request;
In terms of testing, creating automated tests for the first two aspects of this is straightforward. However, testing the function of third aspect is harder.

The IDependencyResolver interface used by MVC makes no provision for releasing components, so to avoid Windsor holding onto our components for too long and leaking memory, the PerWebRequest lifestyle is specified. To the best of my current knowledge, creating an automated test in which to simulate Windsor’s functionality here is not easy, if at all possible. It is possible to override the lifestyle in the test to avoid this exception:

System.InvalidOperationException: HttpContext.Current is null. PerWebRequestLifestyle can only be used in ASP.Net

However, this doesn’t really help as, although we’re testing Windsor functionality, we’re not testing the intent of the code, or the correct Windsor functionality.

I ended-up writing this test:
1:  [Test]  
2:  [Category("Integration")]  
3:  public void Install_ConfiguredInstaller_ShouldRegisterControllersWithPerWebRequestLifestyle()  
4:  {  
5:     ContainerFactory.Install(_container);  
6:    
7:     var controllerHandlers = _container.Kernel.GetAssignableHandlers(typeof(Controller));  
8:    
9:     var misRegisteredComponents =  
10:       controllerHandlers.Where(h => !h.ComponentModel.LifestyleType.Equals(LifestyleType.PerWebRequest));  
11:    
12:    Assert.That(misRegisteredComponents.Any(), Is.False);  
13: }  
While it doesn’t test Windsor’s PerWebRequest lifestyle functionality, it stands as a descriptor of the code’s intent and will flag an unwitting code change. Therefore a test with value, IMHO. However, considering that it doesn’t actually prove the Windsor functionality, is it a valid test?

No comments:

Post a Comment