+1  A: 

Dependency Injection is a great principle that allows you to create tests easily by defining mock objects where needed.

Basically the idea is that you pass in any dependency to an object, it doesn't create its own objects to operate on.

Kekoa
A: 

use a Mock framework to supply test data

http://ayende.com/projects/rhino-mocks.aspx
http://code.google.com/p/moq/
Rony
+3  A: 

Dependency Injection is the solution you are looking for. The general problem has to do with where your dependencies are created. Normally, when writing an object-oriented program, the natural instinct is to create your dependencies directly using the new keyword at the location you need your dependencies. Sometimes you may create long-lived dependencies in a constructor.

To make your classes more unit testable, you need to "invert" that norm, and create your dependencies externally (or create a factory/provider/context that can in turn be injected and used to create instances of other dependencies), and "inject" those dependencies into your class. The two most common mechanisms of injection are either as parameters to a constructor, or with properties with setters. By externalizing dependency management in this way, you are easily able to create mocked versions of those dependencies and pass those in, allowing you to test your units of code in full isolation from the rest of your application.

To support dependency injection and make it easier to manage Inversion of Control (IoC) containers have appeared. An IoC container is a framework that allows you to configure dependency graphs independently of the classes that participate in in those graphs. Once a dependency graph is configured (usually rooted at the single key class of interest), you can easily create instances of your objects at runtime without having to worry about manually creating all of the required dependencies as well. This helps in creating very loosely coupled, flexible code that is easy to reconfigure. An example of a very good IoC container is Castle Windsor, which provides a very rich framework for wiring up classes via dependency injection.

A very simple example of Dependency Injection would be something like the following:

interface ITaskService
{
    void SomeOperation();
}

interface IEntityService
{
    Entity GetEntity(object key);
    Entity Save(Entity entity);
}

class TaskService: ITaskService
{
    public TaskService(EntityServiceFactory factory)
    {
        m_factory = factory;
    }

    private EntityServiceFactory m_factory; // Dependency

    public void SomeOperation() // Method must be concurrent, so create new IEntityService each call
    {
        IEntityService entitySvc = m_factory.GetEntityService();
        Entity entity = entitySvc.GetEntity(...);
        // Do some work with entity
        entitySvc.Save(entity);
    }
}

class EntityServiceFactory
{
    public EntityServiceFactory(RepositoryProvider provider)
    {
        m_provider = provider;
    }

    private RepositoryProvider m_provider; // Dependency

    public virtual IEntityService GetEntityService()
    {
        var repository = m_provider.GetRepository<Entity>();
        return new EntityService(repository);
    }
}

class EntityService: IEntityService
{
    public EntityService(IEntityRepository repository)
    {
        m_repository = repository;
    }

    private IEntityRepository m_repository; // Dependency

    public Entity GetEntity(object key)
    {
        if (key == null) throw new ArgumentNullException("key");

        // TODO: Check for cached entity here?

        Entity entity = m_repository.GetByKey(key);
        return entity;
    }

    public Entity Save(Entity entity)
    {
        if (entity == null) throw new ArgumentNullException(entity);

        if (entity.Key == null)
        {
            entity = m_repository.Insert(entity);
        }
        else
        {
            m_repository.Update(entity);
        }

        return entity;
    }
}

class RepositoryProvider
{
    public virtual object GetRepository<T>()
    {
        if (typeof(T) == typeof(Entity))
            return new EntityRepository();
        else if (...)
            // ... etc.
    }
}

interface IEntityRepository
{
    Entity GetByKey(object key);
    Entity Insert(Entity entity);
    void Update(Entity entity);
}

class EntityRepository: IEntityRepository
{
    public Entity GetByKey(object key)
    {
        // TODO: Load up an entity from a database here
    }

    public Entity Insert(Entity entity)
    {
        // TODO: Insert entity into database here
    }

    public void Update(Entity entity)
    {
        // TODO: Update existing entity in database here
    }
}
jrista
Thank you for this very thorough explanation. I definitely need to do more research on this.
Chris Thompson
Your very welcome. :) I haven't had a chance to do my StackOverflow rounds for a while...you got the benefit of my first answer in a few days.
jrista