Archive for the ‘testing’ Category

Continuous Integration: some posts

Martin Fowler: Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily – leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.

Some posts about Continuous Integration for further reading:

Continuous Integration
How and why do I set up a C# build machine?
Best Continuous Integration Setup for a solo developer (.NET) [closed]
Continuous Integration for Everybody

NHibernate: ORM for .Net

NHibernate website states [1]: “NHibernate is a mature, open source object-relational mapper for the .NET framework. It’s actively developed , fully featured and used in thousands of successful projects.”

I found a demo project by Dario Quintana [4] and updated it, combining it with Getting Started  Guide – Your first NHibernate based application [2].

The demo app on the Getting Started  Guide – Your first NHibernate based application [2] is a little bit buggy, but combining it with Dario Quintana demo I got to understand this NHibernate stuff.

Sample project with full source code here:

https://docs.google.com/open?id=0B7gHrdOYQf9yNmRzeHNjU201eFk

Some code example:

public class Employee 
{ 
public virtual int Id { get; private set; } 
public virtual string FirstName { get; set; } 
public virtual string LastName { get; set; } 
public virtual Store Store { get; set; } 
}

You can notice the following:

  1. Firstly, the Id property has a private setter, this is because it’s only NHibernate that should be setting the value of that Id.
  2. Secondly, all the properties are marked virtual; this is because NHibernate creates “proxies” of your entities at run time to allow for lazy loading, and for it to do that it needs to be able to override the properties.

References:

NHibernate [1]
Your first NHibernate based application [2]
Tutorial de NHibernate – Primeros pasos [3] by Dario Quintana (source code here) [4]
Domain Driven Design by Eric Evans [5]
Lazy Load
Using NHibernate with Visual Studio .NET
Fluent NHibernate
Fluent NHibernate in a Nutshell
fluent-nhibernate / src / Examples.FirstProject / Program.cs
Auto mapping
RavenDB vs MSSQL
Convention over configuration
The Data Driven Conspiracy
An Irrational Love of the Relational
Codd’s 12 rules
Domain-driven design
db4objects
C# Domain-Driven Design sample application
Domain Driven Design: Learning
Domain Driven Design Quickly: free E-Book
NHibernate Best Practices with ASP.NET, 1.2nd Ed.
An Overview of Unit Testing using Visual Studio Team System
Using NUnit in Visual Studio 2010

NAnt: .Net automated builds

Official site

Fundamentals

Build files

Example build file for HelloWorld project:

    <?xml version="1.0"?>
    <project name="Hello World" default="build" basedir=".">
        <description>The Hello World of build files.</description>
        <property name="debug" value="true" overwrite="false" />
        <target name="clean" description="remove all generated files">
            <delete file="HelloWorld.exe" failonerror="false" />
            <delete file="HelloWorld.pdb" failonerror="false" />
        </target>
        <target name="build" description="compiles the source code">
            <csc target="exe" output="HelloWorld.exe" debug="${debug}">
                <sources>
                    <includes name="HelloWorld.cs" />
                </sources>
            </csc>
        </target>
    </project>

 

More references:

Installing NAnt to drive database continuous integration by David Atkinson

How to build a database from source control by David Atkinson

LINQ to SQL DataContext

References:

Linq to SQL DataContext Lifetime Management
Mocking LINQ to SQL DataContext

LINQ and Entity Framework Posts for 2/4/2008+

Implementing the Repository Pattern in C# ASP .NET

Excellent post by Kori Becker: Implementing the Repository Pattern in C# ASP .NET

Source code: here or here

I mean, I got to understand this Repository Patter stuf thanks to this excellent yet simple example.

A class:

public class Planet
{
    public int PlanetId;
    public string Name;
    public bool IsTerraform;

    public Planet()
    {
    }

    public Planet(int planetId, string name, bool isTerraform)
    {
    PlanetId = planetId;
    Name = name;
    IsTerraform = isTerraform;
}
}

An interface:

public interface IPlanetRepository
{
    List<Planet> GetPlanets();
    List<Planet> GetStars();
}

A MS SQL Server repository:

public class MSSQLPlanetRepository : IPlanetRepository
{
    #region IPlanetRepository Members

    public List<Planet> GetPlanets()
    {
    // Simulate returning the list of data from the database.
    List<Planet> planetList = new List<Planet>();

    // SqlConnection code would actually go here, this is to keep things simple.
    planetList.Add(new Planet(1, "Mercury", false));
    planetList.Add(new Planet(2, "Venus", true));
    planetList.Add(new Planet(3, "Earth", true));
    planetList.Add(new Planet(4, "Mars", true));
    planetList.Add(new Planet(5, "Jupiter", false));
    planetList.Add(new Planet(6, "Saturn", false));
    planetList.Add(new Planet(7, "Uranus", false));
    planetList.Add(new Planet(8, "Neptune", false));
    planetList.Add(new Planet(9, "Pluto", false));

    return planetList;
    }

    public List<Planet> GetStars()
    {
    // Simulate returning the list of data from the database.
    List<Planet> planetList = new List<Planet>();

    // SqlConnection code would actually go here, this is to keep things simple.
    planetList.Add(new Planet(1, "Sun", false));

    return planetList;
    }

    #endregion
}

A BussinessLayer:

public class PlanetBusiness
{
    IPlanetRepository _repository;

    public PlanetBusiness(IPlanetRepository repository)
    {
      _repository = repository;
    }

    public List<Planet> GetPlanets()
    {
      return _repository.GetPlanets();
    }

    public List<Planet> GetStars()
    {
      return _repository.GetStars();
    }

    public List<Planet> GetTerraformPlanets()
    {
      // Return the list of filtered data from the database.
      List<Planet> planetList = _repository.GetPlanets();

      var results = from p in planetList
      where p.IsTerraform == true
      select p;

      return results.ToList();
    }
}

Presentation layer:

static void Main(string[] args)
{
    // Load planets from the MSSQL repository.
    PlanetBusiness planetBusiness = new PlanetBusiness(new MSSQLPlanetRepository());

    List<Planet> planetList = planetBusiness.GetPlanets();
    foreach (Planet planet in planetList)
    {
      Console.WriteLine(planet.PlanetId + ". " + planet.Name);
    }
}

An Oracle repository:

public class OracleRepository : IPlanetRepository
{
    #region IPlanetRepository Members

    public List<Planet> GetPlanets()
    {
      // Simulate returning the list of data from the database.
      List<Planet> planetList = new List<Planet>();

      // OracleConnection code would actually go here, this is to keep things simple.
      planetList.Add(new Planet(1, "Mercury", false));
      planetList.Add(new Planet(2, "Venus", true));
      planetList.Add(new Planet(3, "Earth", true));
      planetList.Add(new Planet(4, "Mars", true));
      planetList.Add(new Planet(5, "Jupiter", false));
      planetList.Add(new Planet(6, "Saturn", false));
      planetList.Add(new Planet(7, "Uranus", false));
      planetList.Add(new Planet(8, "Neptune", false));
      planetList.Add(new Planet(9, "Pluto", false));
      planetList.Add(new Planet(10, "Planet X", false));

      return planetList;
    }

    public List<Planet> GetStars()
    {
      // Simulate returning the list of data from the database.
      List<Planet> planetList = new List<Planet>();

      // OracleConnection code would actually go here, this is to keep things simple.
      planetList.Add(new Planet(1, "Sun", false));
      planetList.Add(new Planet(2, "Alpha Centauri", false));

      return planetList;
  }

  #endregion
}

Just change to this in Presentation Layer:

static void Main(string[] args)
{
    // Load planets from the Oracle repository.
    PlanetBusiness planetBusiness = new PlanetBusiness(new OraclePlanetRepository());

    List<Planet> planetList = planetBusiness.GetPlanets();
    foreach (Planet planet in planetList)
    {
      Console.WriteLine(planet.PlanetId + ". " + planet.Name);
    }
}

A Unit Testing repository:

public class TestRepository : IPlanetRepository
{
    #region IPlanetRepository Members

    public List<Planet> GetPlanets()
    {
      // Simulate returning the list of data from the database.
      List<Planet> planetList = new List<Planet>();

      planetList.Add(new Planet(1, "Earth", true));
      planetList.Add(new Planet(2, "Test Planet", true));

      return planetList;
    }

    public List<Planet> GetStars()
    {
      // Simulate returning the list of data from the database.
      List<Planet> planetList = new List<Planet>();

      planetList.Add(new Planet(1, "None", false));

      return planetList;
    }

    #endregion
}

Accessing all repositories at once from Presentation Layer:

static void Main(string[] args)
{
    // Load planets from the MSSQL repository.
    PlanetBusiness planetBusiness = new PlanetBusiness(new MSSQLPlanetRepository());
    TestPlanets(planetBusiness);

    // Load planets from the Oracle repository.
    planetBusiness = new PlanetBusiness(new OracleRepository());
    TestPlanets(planetBusiness);

    // Load planets from the Test repository.
    planetBusiness = new PlanetBusiness(new TestRepository());
    TestPlanets(planetBusiness);

    Console.ReadKey();
}

private static void TestPlanets(PlanetBusiness planetBusiness)
{
    // Basic driver class to test our planet business class and display output.
    Console.WriteLine();
    Console.WriteLine("Planets:");
    Console.WriteLine();

    List<Planet> planetList = planetBusiness.GetPlanets();
    foreach (Planet planet in planetList)
    {
      Console.WriteLine(planet.PlanetId + ". " + planet.Name);
    }

    Console.WriteLine();
    Console.WriteLine("Terraformable Planets:");
    Console.WriteLine();

    planetList = planetBusiness.GetTerraformPlanets();
    foreach (Planet planet in planetList)
    {
      Console.WriteLine(planet.PlanetId + ". " + planet.Name);
    }
}

Using C# .NET reflection to automatically implement the desired concrete repository at run-time, by reading the web.config:

    <appSettings>
    <!-- The assembly name of the default repository. Use the format Fully.Qualified.Class.Name, Assembly.FileName -->
    <add key="DefaultRepository" value="RepositoryPatternTest.Repository.Repositories.MSSQLPlanetRepository, RepositoryPatternTest.Repository" />
    </appSettings>

On Presentation Layer:

static void Main(string[] args)
{
    // Load planets from the default repository as specified in the web.config. Allows for changing the repository at run-time, without changing code!
    Type obj = Type.GetType(ConfigurationManager.AppSettings["DefaultRepository"]);
    ConstructorInfo constructor = obj.GetConstructor(new Type[] { });
    IPlanetRepository defaultRepository = (IPlanetRepository)constructor.Invoke(null);

    PlanetBusiness planetBusiness = new PlanetBusiness(defaultRepository);
    TestPlanets(planetBusiness);

    Console.ReadKey();
}

 

References:

 

Repository by Martin Fowler

ASP.NET MVC using the Repository Pattern on StackOverflow.com

Using the Entity Framework Repository and UnitOfWork Pattern in C# ASP .NET

Using Repository and Unit of Work patterns with Entity Framework 4.0

 

Unit Testing in .Net

Unit Testing in .NET Projects

Mock Objects to the Rescue! Test Your .NET Code with NMock