Archive for April, 2010
Fakes, Mocks, and Stubs, What’s the Difference?
Posted by John in Methodology on April 24, 2010
It doesn’t take much unit testing before you come across a dependency in the class you are testing for another object. Hopefully your classes are loosely coupled and you are able to make a substitution for this other object. It seems most people call these substitute objects mocks but a mock is a specific thing. According to Martin Fowler there are 4 types of substitution:
- Dummy – An object that is never actually used, just required to fill out the parameter list.
- Fake – An object with just enough of a working implementation to substitute.
- Stub – An object that can provide canned answers to member calls and, optionally, record the calls for later interrogation.
- Mock – An object that is programmed with a set of expectations of which calls will be made, in what order with what parameters. It is the expectation that is tested after the code has been exercised.
Entity Classes, IDs and Equality
Posted by John in Methodology on April 22, 2010
I want my entity classes to rely on their ID when checking equality, the ID is populated from the repository when I retrieve an object and automatically generated when I save a new entity.
This poses the problem of how I compare two entities before they have been saved while working with them in my domain, or, when I have ‘newed’ them up myself for unit testing. The answer is to use a transient ID.
Normally an Entity Base class might look like this:
public abstract class EntityBase : IEquatable<EntityBase> {
public virtual int Id { get; protected set; }
public override bool Equals(object other) {
return Equals(other as EntityBase);
}
public override int GetHashCode() {
return Id;
}
public virtual bool Equals(EntityBase other) {
if (other == null) return false;
return other.Id == Id && other.GetType() == GetType();
}
}
If two new objects are created from a derived class then object1.Equals(object2) will be true as Id will be 0 for both objects. To avoid this I need to check if an object has not yet been saved:
private bool IsTransient {
get { return Id == 0; }
}
And just check for referential equality if this is the case:
public virtual bool Equals(EntityBase other) {
if (other == null) return false;
if (IsTransient) return ReferenceEquals(this, other);
return other.Id == Id && other.GetType() == GetType();
}
GetHashCode() needs to be overridden to reflect this:
public override int GetHashCode() {
if (IsTransient) return base.GetHashCode();
return Id;
}
The full code for EntityBase is:
public abstract class EntityBase : IEquatable<EntityBase> {
public virtual int Id { get; protected set; }
private bool IsTransient {
get { return Id == 0; }
}
public override bool Equals(object other) {
return Equals(other as EntityBase);
}
public override int GetHashCode() {
if (IsTransient) return base.GetHashCode();
return Id;
}
public virtual bool Equals(EntityBase other) {
if (other == null) return false;
if (IsTransient) return ReferenceEquals(this, other);
return other.Id == Id && other.GetType() == GetType();
}
}
Solution Layout for an MVC App
While it may seem easier to throw all code into one project, it is good practise to separate areas of code into different projects within a solution. This helps promote good design with principles like loose coupling and high cohesion. A solution layout I like is:
- Domain – contains the domain layer and data interfaces (in their own sub folder) and, if necessary can reference the Infrastructure project.
- DataInterfaces *
- Infrastructure – contains plumbing code for functions such as logging and reporting, should not reference any other projects.
- Logging
- Reporting
- Infrastructure.Data – contains data access code and references the Core and Infrastructure projects. Whilst some may put this in the infrastructure project, I prefer Domain to be able to reference Infrastructure which causes a circular reference if data access code is kept there.
- Tests – self explanatory – references any projects that need tests. Each project has a subfolder to contain it’s tests
- Core
- Data
- Web.Controllers
- Web – contains the core of the MVC project including the views and Global.asax, some files and folders have been moved around and models and controllers have been moved into different projects. The web project references all other projects except Test.
- Public
- css
- images
- javascript
- Views
- Public
- Web.Controllers – contains the controllers and also the RouteRegistrar class. Splitting the controllers into their own project does cause some extra initial work but a good argument for doing this can be found here.
*Indented items represent folders and sub folders within the projects.
The Solution Explorer should look similar to this when done:
All projects are class libraries except for the Web project which is MVC2. Web Content folder has been renamed to public and sub folders added and script and css files moved into it. HomeController has been moved to the Controllers project and the Controllers and Models folders have been deleted.
To get this solution to run:
- Set Web as Start Up Project
- Add a reference to Web.Controllers from Web.
- Add a references to System.Web, System.Web.MVC (2.0.0.0) and System.Web.Routing from Web.Controllers.
- Add the RouteRegistrar class to Web.Controllers.
- Amend Global.asax.cs Application_Start to use RouteRegistrar.RegisterRoutes.
using System.Web.Mvc;
using System.Web.Routing;
namespace Furld.Web.Controllers {
public class RouteRegistrar {
#region Class Methods
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
}
#endregion
}
}
I also have a preferred folder structure which looks like this:
- Main project folder – this is what gets committed to source control
- Docs
- Lib – contains all libraries I reference (e.g. nunit.framework.dll, ninject.dll etc).
- Src – contains the solution file and the projects, each in it’s subfolder (Core, Data …).
- Tools – contains tools used in the project, both those that require installation and those where I am just using libraries (e.g. NUnit-2.5.4.10098.zip).
This layout has a few changes from my normal layout partly prompted by Rob Conery’s http://mvcstarter.codeplex.com/ and some investigation of http://www.sharparchitecture.net/.
Azure Development Fabric and Visual Studio 2010
Just installed Visual Studio 2010. The first thing I tried was creating an new Cloud project.
The whole process was surprisingly painless. After creating the solution, I was prompted to download and install the Azure tools. Once they were installed, I deleted and recreated the solution and was prompted for which Roles I wanted:
After creating the solution just hit F5 to see the project running in the Azure Development Fabric.
The debugger is already connected and all works just as you would expect.