Testing Code Contracts .NET 4.0

Why use Code Contracts?

By providing pre-compiled code contract interfaces other developers can adhere to signatures and also expected behavior. This is specially important due to the Liskov substitution principle.

Dino Esposito wrote a great article on the topic called Code Contracts Preview: Interfaces.

Testing

To test that all the right contracts are in place a test project can be created.

Testing preconditions is possible by catching the exceptions created by those preconditions.


        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void ModelNegativeBlance()
        {
            Account acc = new Account()
            {
                AccountName = "NewAccount",
                //0 or positive is expected
                Balance = -99,
                CreationDate = DateTime.Now

            };
        }

Testing postconditions is a bit tricky because the exceptions raised by postconditions are not meant to be caught. Therefore plain strings have to be used.


    public static class TestHelpers
    {
        public static string ContractExceptionName = "System.Diagnostics.Contracts.__ContractsRuntime+ContractException";

    }
    public class RepositoryTests
    {
        public RepositoryTests()
        {

        }

        [TestMethod]
        public void InsertModelWithNoParitionKeyDueToBadRepository()
        {

            var repo = SetBadRepo();
            Account acc = new Account()
            {
                AccountName = "NewAccount",
                Balance = 0,
                CreationDate = DateTime.Now

            };

            try
            {
                repo.InsertAccount(acc);
            }
            catch (Exception ex)
            {
                Assert.AreEqual(TestHelpers.ContractExceptionName, ex.GetType().FullName);
            }
        }
    }

LINQ-To-SQL Improving Performance

Linq to SQL is great. I love it because it adds a simple abstraction layer that can greatly speed up building a data access layer.

If not used properly, LINQ to SQL can also create performance issues. Here are my general LINQ to SQL guidelines when I work in projects:


Use the “using” statement when working with a context

This is mostly a general C# programming guideline but there have been several times when I see programmers missing this step. Here is more information from MSDN.

The using statement allows the programmer to specify when objects that use resources should release them. The object provided to the using statement must implement the IDisposable interface. This interface provides the Dispose method, which should release the object’s resources.

using statement can be exited either when the end of the using statement is reached or if an exception is thrown and control leaves the statement block before the end of the statement.

Here is an example:

using (NorthwindDataContext context = new NorthwindDataContext())
{
  //do stuff here
}


Compiled queries

To query something with LINQ to SQL there are several “startup” procedures. This procedures are not too bad when queries are not used too often. If the same query is done several times, its heavy and it is the core of the product then it is VERY important to make it a compiled query.

I will not go into too many details about this because there are several posts about the subject:


Use multiple tiny contexts instead of big bulky ones

Contexts are meant to keep track of the objects in the database. By having small contexts with a single purpose then the burden of tracking is lessen and therefore there is less memory consumption.


Do not keep track of object changes in the database unless its needed

There are two good ways to improve the performance of queries that do not involve concurrency issues:

  1. Optimistic concurrency  = off
  2. Object tracking = off

For object tracking, is super easy to turn off:

context.ObjectTrackingEnabled = false;

Sadly, as  Rick Strahl covers in his blog there are a few things/issues to consider when turning off Object Tracking.


Combine Queries and custom expressions

Combining queries is a good idea when working with databases, just grab what you need and aggregate the data into a POCO model or anonymous type. Finally, if extreme fine control is needed, there is always custom expressions.

Dynamic Azure Web Services URLs

I am currently building a lot of web services for Azure. Since URLs change a lot in development and deployment environments I needed to be able to have those services URLs updated dynamically. The easiest way I found is using handlers and:


HttpContext.Current.Request.Headers["Host"];

This way none of the URLs get hard-coded and deployment is extremely easy. This also brings a lot of neat options for Intercloud communication, but that is for another post.

Unitiy IOC

Basically, with Unity, I ended up writing something like this (simplified version) :

IUnityContainer container = new UnityContainer();

container.RegisterType<IRiskRepository, RiskRepository>();

string conn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

container.Configure<InjectedMembers>().ConfigureInjectionFor<RiskRepository>(new InjectionConstructor(conn));

UnityControllerFactory factory = new UnityControllerFactory(container);

ControllerBuilder.Current.SetControllerFactory(factory);

Unity turned out to work very well. I was able to save a lot of lines of code and it is greatly improving the testability of the dynamic modules I am using on the mock project architecture. Also, it was easy to set up. Its a good alternative to the other more popular IOC.

Conditional Debug mode

Sometimes we have to implement code that is only meant to work for us as developers and not the our clients. That is when conditional debug comes to play. Using conditional debug it is possible to only allow some functions to be called only if the project is running in debug mode.

I found it useful on the following scenarios:

  • Impersonation – change my context to a specific user contex.
  • Tracing/Profiling
  • Testing

[Conditional("DEBUG")]

  public void OnlyRunIfUnderDebug(string person)
       {
           //replace context with person's arguments context
           //profiling
           //testing
           //etc
       }