Active Conventions with NDepend – Part Deux

I want to put out a short sequel to my previous post on Active Conventions with NDepend. Also make sure to read Patrick Smacchia’s follow-up if your interested.

As you may or may not know, I’m a huge fan of using Test Data Builders for setting up the context for the domain objects in my BDD specifications.

[TestFixture] public class When_performing_something_action_with_an_order { [SetUp] public void Establish_context() { _order = new OrderBuilder() .WithCustomer(new CustomerBuilder() .WithFirstName("Homer") .WithLastName("Simpson")) .ForProduct(new ProductBuilder() .WithName("Saxomofoon")) } ... }

The biggest benefit of using the Builder pattern this way, is the fact that the creation of domain objects gets decoupled from the specifications itself. The constructor of a domain object gets called only at a single place in the code. If I wanted to add a new parameter to the constructor, I only have to change it in one place.

The following CQL statement ensures that the Test Data Builders are used instead of directly calling the constructors of the domain objects:

// <Name>Test data builders are not used by SetUp methods.</Name> WARN IF Count > 0 IN SELECT METHODS WHERE (HasAttribute "NUnit.Framework.SetUpAttribute" OR NameIs "Before_each_specification") AND ((IsDirectlyUsing "NAMESPACE:MyProject.Domain.Model" OR IsDirectlyUsing "NAMESPACE:MyProject.Domain.DTO") AND !IsDirectlyUsing "NAMESPACE:MyProject.Domain.UnitTests.Builders")

Although its probably not 100% foul proof, this CQL constraint detects the most blatant violations.

Till next time,

Jan, the NDepend addict.

2 thoughts on “Active Conventions with NDepend – Part Deux

  1. I am not sure it’d help in your sample, but I precise there is a CreateA and DepthOfCreateA CQL conditions. For example, the following CQL rule make sure that there is no instance of Nm1.Foo created outside of namespace Nm2:

    DepthOfCreateA “Nm1.Foo” == 1

Comments are closed.