Saturday, March 20, 2010

Testing multiple implementations

Challenge: Run automated tests of multiple implementations of an interface, for example one repository for Sql Server and another for MySql.

A solution: Have one test class for one of the implementations, and create a derived test class for the other implementation, which injects the proper implementation in the constructor of the first test class.

Example with NUnit:

[TestFixture]
public class CustomerRepositoryTests
{
   private ICustomerRepository _repository;

   public CustomerRepositoryTests() :
      this(new CustomerRepository())
   {
   }

   public CustomerRepositoryTests(ICustomerRepository repository)
   {
      _repository = repository;
   }

   [Test]
   public void Add_ValidCustomer_Ok()
   {
      // Arrange:
      var customer = new Customer();

      // Act:
      _repository.Add(customer);
   }

}

[TestFixture]
public class MySqlCustomerRepositoryTests :
   CustomerRepositoryTests
{
   public MySqlCustomerRepositoryTests() :
      base(new MySqlCustomerRepository())
   {
   }
}

Wednesday, March 17, 2010

Manual definition of dependent tables with LinqToSql

The following is a code example of how to declare dependent tables in C# and generate and populate them with LinqToSql [it will generate the tables Parent(Id, Name, ChildId) and Child(Id, Name)]:

using System;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace ManualLinqToSql
{
   class Program
   {
      static void Main(string[] args)
      {
         const string connectionString =
            @"Server=.\SqlExpress;Database=LinqTest;Integrated Security=true;";
         TestRepository repository =
            new TestRepository(connectionString);
         try
         {
            repository.CreateDatabase();
            repository.Add("A", "A1");
            repository.Add("B", "B1");
            Console.WriteLine("OK");
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex);
         }
         Console.ReadKey();
      }
   }

   public class TestRepository
   {
      private readonly TestDataContext _dataContext;

      public TestRepository(string connectionString)
      {
         _dataContext = new TestDataContext(connectionString);
      }

      public void Add(string parentName, string childName)
      {
         var parent = new Parent(parentName, childName);
         _dataContext.ParentTable.InsertOnSubmit(parent);
         _dataContext.SubmitChanges();
      }

      public void CreateDatabase()
      {
         _dataContext.DeleteDatabase();
         _dataContext.CreateDatabase();
      }
   }

   public class TestDataContext : DataContext
   {
      public TestDataContext(string connectionString)
         : base(connectionString)
      {
      }

      public Table<Parent> ParentTable
      {
         get { return GetTable<Parent>(); }
      }

      public Table<Child> ChildTable
      {
         get { return GetTable<Child>(); }
      }
   }

   [Table]
   public class Parent
   {
      private EntityRef<Child> _child;

      public Parent()
      {
      }

      public Parent(string name, string childName)
      {
         Name = name;
         Singleton = new Child { Name = childName };
      }

      [Column(IsPrimaryKey = true, IsDbGenerated = true)]
      public int Id { get; set; }

      [Column(CanBeNull = false)]
      public string Name { get; set; }

      [Association(Storage = "_child", ThisKey = "ChildId", IsForeignKey = true)]
      public Child Singleton
      {
         get
         {
            return _child.Entity;
         }
         set
         {
            _child.Entity = value;
            ChildId = value.Id;
         }
      }

      [Column(UpdateCheck = UpdateCheck.Never)]
      private int ChildId { get; set; }
   }

   [Table]
   public class Child
   {
      [Column(IsPrimaryKey = true, IsDbGenerated = true)]
      public int Id { get; set; }

      [Column(CanBeNull = false)]
      public string Name { get; set; }
   }

   public void Detach()
   {
      _child = default(EntityRef<Child>);
   }
}

Sunday, March 7, 2010

MSBuild: Passing arrays between targets

In MSBuild, if you have a target that operates on a list of items of a specific type, and you want to call that operation several times with different lists, here is a way to do that using the DependsOnTargets attribute:

<Target Name="UserInterface">
  <MSBuild Projects="$(MSBuildProjectFile)" Targets="Service"
    Properties="ServiceDependsOn=PersonRepository-1" />
  <MSBuild Projects="$(MSBuildProjectFile)" Targets="Service"
    Properties="ServiceDependsOn=PersonRepository-2" />
</Target>

<Target Name="Service" DependsOnTargets="$(ServiceDependsOn)">
  <Message Text="Persons: @(Persons->'%(Name) (%(Identity))')" />
</Target>

<Target Name="PersonRepository-1">
  <ItemGroup>
    <Persons Include="Al"><Name>Al Omaha</Name></Persons>
    <Persons Include="Ben"><Name>Ben Patterson</Name></Persons>
  </ItemGroup>
</Target>

<Target Name="PersonRepository-2">
  <ItemGroup>
    <Persons Include="Adrian"><Name>Adrian Quist</Name></Persons>
    <Persons Include="Britta"><Name>Britta Ruud</Name></Persons>
  </ItemGroup>
</Target>


and here is sample output:

Project "C:\Projects\MSBuildItems.xml" on node 0 (default targets).
Project "C:\Projects\MSBuildItems.xml" (1) is building "C:\Projects\MSBuildItems.xml" (1:2) on node 0 (Service target(s)).
 Persons: Al Omaha (Al);Ben Patterson (Ben)
Done Building Project "C:\Projects\MSBuildItems.xml"
(Service target(s)).

Project "C:\Projects\MSBuildItems.xml" (1) is building "C:\Projects\MSBuildItems.xml" (1:3) on node 0 (Service target(s)).
 Persons: Adrian Quist (Adrian);Britta Ruud (Britta)
Done Building Project "C:\Projects\MSBuildItems.xml"
(Service target(s)).

Done Building Project "C:\Projects\MSBuildItems.xml" (default targets).

MSBuild with dependency injection

I am about to start refactoring a MSBuild file with around 1000 lines of xml, and I find that the targets are heavily dependent on each other.

Maybe dependency injection can help here?!

In MSBuild this could look something like this:

UserInterface.xml:
<Import Project="ApplicationService.xml" />
<Import Project="Repository.xml" />
(or <Import Project="FakeRepository.xml" />)
<Target Name="UserInterface-Action">
  <CallTarget Targets="ApplicationService-Action" />
</Target>


ApplicationService.xml:
<Target Name="ApplicationService-Action">
  <CallTarget Targets="IRepository-Action" />
</Target>


Repository.xml:
<Target Name="IRepository-Action">
  <Message Text="Repository action" />
</Target>


FakeRepository.xml:
<Target Name="IRepository-Action">
  <Message Text="Fake repository action" />
</Target>


For comparison, here is the corresponding structure in C#:
public class UserInterface
{
  private readonly IRepository repository;

  public UserInterface(IRepository repository)
  {
    this.repository = repository;
  }

  public void Action()
  {
    var service = new ApplicationService(this.repository);
    service.Action();
  }
}

public class ApplicationService
{
  private readonly IRepository repository;

  public ApplicationService(IRepository repository)
  {
    this.repository = repository;
  }
  
  public void Action()
  {
    this.repository.Action();
  }
}

public interface IRepository
{
  void Action();
}

public class Repository : IRepository
{
  public void Action()
  {
    System.Console.WriteLine("Repository action");
  }
}

public class FakeRepository : IRepository
{
  public void Action()
  {
    System.Console.WriteLine("Fake repository action");
  }
}