HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Chained Assertions

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
assertionschainedstackoverflow

Problem

Wouldn't it be nice to just chain assertions after a method call or is it just me? I was thinking that it'd improve readability.

Instead of:

var myObject = _objectService.GetRandomObject();
Trace.Assert(myObject!=null);


it'll just be this:

_objectService.GetRandomObject().NeverNull();


with the extension method defined as

namespace System
{
    public static class AssertionExtensions
    {
        public static T NeverNull(this T obj) 
            where T : class
        {
            Trace.Assert(obj != null);
            return obj;
        }
    }
}


We could make extensions for some of the most common assertions:

public static T Never(this T obj, bool condition) 
    where T : class
{
    Trace.Assert(!condition);
    return obj;
}

public static T Always(this T obj, bool condition) 
    where T : class
{
    Trace.Assert(condition);
    return obj;
}


If one prefers exceptions over asserts, that's a possibility too.

Solution

I use Code Contracts to take care of my assertions.

Contract.Requires(customer.Age > 0);
Contract.Requires(!string.IsNullOrWhitespace(customer.Name));
Contract.Requires(customer.RegisteredProduct.Any());
Contract.Ensures(Contract.Result != null);


It can do several things that extension methods can never do:

  • Show you the source code of the tested expression (although FluentAssertions can approximate that by using expressions, it has the disadvantage of performance and being restricted to using their custom comparison methods (or the more verbose lambdas) as opposed to simple boolean evaluated expressions (like in Debug.Assert(...))



  • Perform assertions on return values, regardless of how many return statements you have in your method.



  • Expose additional metadata about the method via tools (so that IntelliSense shows the contracts).



  • Apply a contract to an interface, where all implementers automatically inherit the assertions.



  • Perform compile-time verifications of the contract, if you're using the Premium or Ultimate versions of Visual Studio. EDIT: Version 1.5 now also support the Professional edition.

Code Snippets

Contract.Requires(customer.Age > 0);
Contract.Requires(!string.IsNullOrWhitespace(customer.Name));
Contract.Requires(customer.RegisteredProduct.Any());
Contract.Ensures(Contract.Result<SupportTicket> != null);

Context

StackExchange Code Review Q#5407, answer score: 3

Revisions (0)

No revisions yet.