Software Is Hardwork

ISimplicityAffinative: The endless pursuit of anti-complexity.
The technology-centric blog of D. P. Bullington.

Email D. P. Bullington View D. P. Bullington\ Get Software Is Hardwork code on CodePlex

Blog Post(s)

Unit Testing Generic Types
Thursday, November 15, 2007

Generics make many coding tasks easier but do introduce subtle unit testing challenges. Consider the following code examples:

public class Contoso<T>
    where T : IWoodgrove, new()
{
    public Contoso() {}
 
    public void MakeMagic()
    {
        T t;
        t = new T();

        // use t...
    }
}

public class Fabrikam<T>
    where T : IWoodgrove
{
    public Fabrikam(T t)
    {
        this.t = t;
    }

    private readonly T t; 

    public void MakeMagic()
    {     
        // use this.t...
    }
}

The Contoso`1 class uses an instance of type T many times and class Fabrikam`1 uses a single instance of type T for its entire lifetime. These two designs affect how one would go about unit testing for incorrectness and correctness. If you truly wanted to test the interaction between Contoso`1/T and Fabrikam`1/T, then you would introduce mock objects into your unit test via some type mocking library (NMock2, RhinoMocks, etc.). The problem is that you cannot dynamically mock a generic parameter since it is static in nature. The solution for a Contoso`1 style of generic class is to create a non-generic super class leveraging a factory interface parameter. Consider:
public interface ITeeFactory
{
    IWoodgrove Create();
}

public class Contoso
{
    public Contoso(ITeeFactory teeFactory)
{
    this.teeFactory = teeFactory;
}

    private ITeeFactory teeFactory;
  
    public void MakeMagic()
    {
        IWoodgrove t;
        t = this.teeFactory.Create();

        // use t...
    }
}

public class GenericTeeFactory<T> : ITeeFactory
    where T : IWoodgrove
{
public IWoodgrove Create()
{
        return new T();
}
}

public class Contoso<T>
    where T : IWoodgrove, new()
{
    public Contoso() : base(new GenericTeeFactory<T>()) {}
}

The solution for a Fabrikam`1 style of generic class is to create a non-generic super class leveraging a typical dependency injection model. Consider:
public class Fabrikam
{
    public Fabrikam(IWoodgrove t)
    {
        this.t = t;
    }

    private readonly IWoodgrove t;  

    public void MakeMagic()
    {      
        // use this.t...
    }
}

public class Fabrikam<T> : Fabrikam
    where T : IWoodgrove
{
    public Fabrikam(T t) : base(t)
    {
    }
}

With these two solutions in hand, mocking these styles of classes becomes easy. (NOTE: Stream of thought coding in examples above. Not tested to ensure compilation.)

Live and Die by the Command Line
Tuesday, November 6, 2007

Just a quick thought as I am heavy into coding this morning: I use the command line just as much as I use the IDE. I find myself invoking iisreset, msbuild, tf, tfpt, svcutil, regsvc32 (oh no, COM!), net, nant, nunit, xcopy, dir, and more... No matter how fancy a smart your IDE, the command line will never die. Now if I was not so lazy, I would get acquainted with PowerShell.

Speaking Enagements

  • 11/18/2010 | Charlottesville .NET Users Group | Charlottesville, VA | Topic TBD
  • 09/14/2010 | Hampton Roads .NET Users Group | Cheaspeake, VA | Topic TBD
  • 07/01/2010 | Richmond .NET Users Group | Richmond, VA | Topic TBD
  • (past) 12/08/2009 | Hampton Roads .NET Users Group | Cheaspeake, VA | SharePoint Antithesis - A Case Study in Pragmatic Software Architecture and Engineering Processes
  • (past) 10/04/2009 | Richmond Code Camp 2009.2 | Richmond, VA | Soothing the Pain Points: Data Access, Validation, Rules, UI, Presentation, et. al
  • (past) 07/23/2009 | Charlottesville .NET Users Group | Charlottesville, VA | Debugging on the Windows Platform
  • (past) 05/23/2008 | NoVa CodeCamp 2009.01 | Reston, VA | Going Proxy-less - The WCF Proxy Factory
  • (past) 04/25/2009 | Richmond Code Camp 2009.1 | Richmond, VA | Software Programmer to Software Engineer: Concepts to Span the Divide
  • (past) 02/05/2009 | Richmond .NET Users Group | Richmond, VA | Debugging on the Windows Platform
  • (past) 10/04/2008 | Richmond Code Camp 2008.2 | Richmond, VA | Going Proxy-less - The WCF Proxy Factory

Blog Archive

Post Labels

.NET (64) .NETv4.0 (3) ACID (1) ActiveDirectory (1) ADF (2) Affiliate (1) Agile (6) AJAX (1) Allocator (3) Analysis (1) AOP (4) ASP.NET (6) ASP.NET MVC (1) Assembly (2) BadIdeaPile (1) BagOfBolts (5) Blogger (1) Books (2) BuildMgmt (8) C# (46) ChoDNUG (1) CLR (1) CLRv4.0 (2) CMP (1) CMS (2) CodeCamp (2) COM (1) Conversation (1) Coverage (1) CUI (1) Database (2) DDD (1) DeadFxs (1) Debugging (9) Design (4) DevAuto (3) DevCfg (1) Development (118) DI (6) DiffMerge (1) Domain (1) DTfW (2) EclipseIDE (1) ECM (1) EntityFramework (1) Estimating (1) FileShare (1) Frameworks (7) GAC (2) Google (1) Hardware (2) HRNUG (1) Humor (6) IIS (4) ILDASM (1) Impersonation (2) InstallError (1) IoC (6) KingTodd (1) LinkedIn (1) LINQtoSQL (2) MarketingHype (1) MBUnit (1) Mentoring (22) Metadata (1) Microsoft (7) MOSS2007 (5) MSBuild (2) MSIL (4) MSSCCI (2) NAnt (2) NCore (2) NCover (1) NDatabase (4) NetUse (1) NHibernate (2) NoVaCodeCamp (2) NTSD/CDB (2) NUnit (1) Observation (2) Office (2) OOD (7) OOP (6) OpenSource (14) Opinion (19) Personal (3) PMP (1) Polymorphism (1) PowerPoint (1) PowerShell (2) Presentation (3) Process (4) ProjectManagement (2) PublicKeyToken (1) QA (2) RDNUG (1) Reflection (2) Registry (2) Resharper (1) Reversing (2) RichmondCodeCamp (5) SCM (11) Scrum (5) Security (2) Series (3) Server2008 (4) ServicePack (1) SES (7) SharePoint (7) Silverlight (1) SoC (3) Software (49) SoftwareIsHardwork (17) Speaking (7) SQL (2) SSO (2) StrongName (2) Suite2008 (9) Suite2010 (1) SwEng (19) TechBlunder (1) Testing (14) Thread (3) Tools (8) Troubleshooting (10) Twitter (3) Types (2) UAC (1) UIP (1) Vault (2) VB6 (1) VC (1) Vista (3) VisualStudio (15) VSIP (2) VSTS (1) WCF (4) Web (4) WebForms (1) Win32 (3) WinDBG (3) WindowsIdentity (3) WinForms (1) WIT (1) Workhorse (1) WoW64 (1) WPF (1) WSS3 (2) x64 (2) x86 (2) xUnit (1)

Disclaimer

© D. P. Bullington, all rights reserved. Everything posted on this blog is my personal opinion and does not represent the views of my employer nor serves to infringe on the sovereignty of any nation.