Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Friday, September 16, 2011

Seterlund.CodeGuard is now on NuGet

My small guard library is now available on NuGet.

The package name is Seterlund.CodeGuard and is available under the New BDS License.

The Guard.That(...) will throw an exception, when some condition is not met

public void SomeMethod(int arg1, int arg2)
{
    // This line will throw an exception when the arg1 is less or equal to arg2
    Guard.That(() => arg1).IsGreaterThan(arg2);

    // This will check that arg1 is not null and that is in some range 1..100
    Guard.That(arg2).IsNotNull().IsInRange(1,100);

    // Several checks can be added.
    Guard.That(arg1)
      .IsInRange(100,1000)
      .IsEven()
      .IsTrue(x => x > 50, "Must be over 500");

    // Do stuff
}


The Validate.That(...) method makes it possible to return a list of all error conditions

public void OtherMethod(int arg1)
{
    // Get a list of errors
    List<string> errors = Validate.That(() => arg1).IsNotNull().GetResult();
}
---
Share:

Thursday, April 7, 2011

Guard your code

You can call it code contracts or an argument guard. This is a simple implementation that can validate that the current state of a variable or method is as you expect it to be. If the validation fails, an exception is thrown. Example code:
public void SomeMethod(int arg1, int arg2)
{
    // This line will throw an exception when the arg1 is less or equal to arg2
    Guard.Check(() => arg1).IsGreaterThan(arg2);

    // This will check that arg1 is not null and that is in some range 1..100
    Guard.Check(arg2).IsNotNull().IsInRange(1,100);

    // Do stuff
}
Source code can be found on GitHub
Share:

Thursday, November 4, 2010

XmlTidy

Needed a tool to tidy some Xml in "Programmer's Notepad" and could not resist to created my own version of XmlTidy. :-)

using System;
using System.Xml;
using System.Xml.XPath;

namespace XmlTidy
{
    public class Program
    {
        private enum ExitCodes
        {
            Success = 0,
            Failure = 1
        }

        private static int Main(string[] args)
        {
            if (args.Length == 0)
            {
                return ShowUsage();
            }

            var inputFile = args[0];
            var outputFile = args.Length == 1 ? args[0] : args[1];
            return Tidy(inputFile, outputFile);
        }

        private static int ShowUsage()
        {
            Console.WriteLine("Usage: XmlTidy <inputfile> <outputfile>");
            Console.WriteLine("if <outputfile> is not specified, the <inputfile> is overwritten.");
            return (int)ExitCodes.Success;
        }

        private static int Tidy(string inputFile, string outputFile)
        {
            var result = (int)ExitCodes.Success;
            try
            {
                var document = new XPathDocument(inputFile);
                var settings = new XmlWriterSettings { IndentChars = "\t", Indent = true };
                var writer = XmlWriter.Create(outputFile, settings);
                document.CreateNavigator().WriteSubtree(writer);
                writer.Close();
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                result = (int)ExitCodes.Failure;
            }

            return result;
        }
    }
}

Share:

Monday, October 11, 2010

Friday, October 1, 2010

Howto create unit test for privat, internal, and friend methods

Problem: You have a class with a private method that you wish to test.
public class ClassUnderTest
{
  private int DoSomePrivateStuff()
  {
     // Something is happening here
  }
} 
Since the method is private you can not access the it from the outside of the object.

How I solved this earlier was to make a testable class that inherited from the class I wanted to test.
public class TestableClassUnderTest : ClassUnderTest
{
  public int DoSomePrivateStuff()
  {
     base.DoSomePrivateStuff();
  }
} 

I now could do the following.
[TestClass]
public class ClassUnderTestTests
{
  [TestMethod]
  public void DoSomePrivateStuff_WhenCalled_ReturnsZero()
  {
     //Arrange
     var testClass = new TestableClassUnderTest();
     //Act
     var actual = testClass.DoSomePrivateStuff();
     //Assert
     Assert.AreEqual(0, actual);
  }
}

This is the classic Extract and Override pattern and there is nothing wrong with it.
But as a colleague showed me today, there is another way when you are using Visual Studio.
  1. Goto the ClassUnderTest in visual studio and right click. Select "Create Private Accessor" and select the test project you want this accessor in.
  2. Go to the test project you choose in step 1. You will now have a project folder called "Test References" with one file ending with ".accessor".
And that's it. VS have now created a class for you with the name "_accessor" that you can use in your tests. My example from above can now be rewritten to the following:
[TestClass]
public class ClassUnderTestTests
{
  [TestMethod]
  public void DoSomePrivateStuff_WhenCalled_ReturnsZero()
  {
     //Arrange
     var testClass = new ClassUnderTest_accessor();
     //Act
     var actual = testClass.DoSomePrivateStuff();
     //Assert
     Assert.AreEqual(0, actual);
  }
}
What's nice about this is that you don't need to create a bunch of testable classes. They are automagically created with reflection for you. Now you got more time to do fun stuff.... :-)

You can read more about this here: http://msdn.microsoft.com/en-us/library/bb385974.aspx

Share:

Wednesday, September 29, 2010

Testing exceptions in unit test

NUnit has a nice feature (Assert.Throws) that makes it possible to assert that a exception is thrown inside some code.

Visual Studio Unit Testing Framework seem to miss this feature and to check that the correct exception is thrown you would could use the following code:
[TestMethod]
public void WithTryCatch()
{
    // Arrange
    ApplicationException actualException = null;

    // Act
    try
    {
        ThrowSomeException();
    }
    catch (ApplicationExceptionex)
    {
        actualException = ex;
    }

    // Assert
    Assert.IsNotNull(actualException);
    Assert.AreEqual("Message", actualException.Message);
}

ExpectedExceptionAttribute
Using the ExpectedExceptionAttribute is possible. In the example below you expect a exception of type ApplicationException with the message set to "ExceptionMessage". All derived exceptions from ApplicationException will also satisfy the test.
[TestMethod]
[ExpectedException(typeof(ApplicationException), "ExceptionMessage", true)]
public SomeTest()
{
    DoSomething();
}

ExceptionAssert
The ExpectedExceptionAttribute could be enough in many situations. But it will not make you able to test specific attributes on an exception or the value of its inner exception. So why not make things it a little easier and more flexible with a helper class.
[TestMethod]
public void WithHelperClass()
{
    // Arrange
    // Act
    // Assert
    ExceptionAssert.Throws<ApplicationException>(
        () => ThrowSomeException(),
        ex => Assert.AreEqual("Message", ex.Message));
}
The Throws method catches the exception specified and will run the asserts on it. If no (or wrong) exception is thrown the test will fail.

The source code for the helper class can be found below.
[DebuggerStepThrough]
public static class ExceptionAssert
{
 /// 
 /// Asserts that an exception of type T is not thrown
 /// 
 /// >Typeparam name="T">Exception to look for
 /// Action to execute
 public static void DoesNotThrow<T>(Action action) where T : Exception
 {
  if (action == null)
  {
   throw new ArgumentNullException("action");
  }

  Exception actualException = null;
  try
  {
   action();
  }
  catch (T ex)
  {
   actualException = ex;
  }

  if (actualException != null)
  {
   throw new AssertFailedException(String.Format(
    "ExceptionAssert.DoesNotThrow failed. Exception <{0}> thrown with message <{1}>",
    actualException.GetType().FullName,
    actualException.Message));
  }
 }

 /// 
 /// Asserts that an exception is not thrown
 /// 
 /// Action to execute
 public static void DoesNotThrow(Action action)
 {
  DoesNotThrow(action);
 }

 /// 
 /// Asserts that an exception of type T is thrown
 /// 
 /// Exception to look for
 /// Action to execute
 public static void Throws<T>(Action action) where T : Exception
 {
  if (action == null)
  {
   throw new ArgumentNullException("action");
  }

  Exception actualException = null;
  try
  {
   action();
  }
  catch (Exception ex)
  {
   actualException = ex;
  }

  ValidateThrownException<T>(actualException, null);
 }

 /// 
 /// Asserts that an exception of type T is thrown
 /// 
 /// Exception to look for
 /// Action to execute
 /// Additional assert to be made on the exception
 public static void Throws<T>(Action action, Action<T> asserts) where T : Exception
 {
  if (action == null)
  {
   throw new ArgumentNullException("action");
  }

  Exception actualException = null;
  try
  {
   action();
  }
  catch (Exception ex)
  {
   actualException = ex;
  }

  ValidateThrownException(actualException, asserts);
 }

 /// 
 /// Asserts that an exception of type T is thrown
 /// 
 /// Exception to look for
 /// Action to execute
 /// Additional assert to be made on the exception
 /// Cleanup action to be executed.
 public static void Throws<T>(Action action, Action<T> asserts, Action finalAction) where T : Exception
 {
  if (action == null)
  {
   throw new ArgumentNullException("action");
  }

  Exception actualException = null;
  try
  {
   action();
  }
  catch (Exception ex)
  {
   actualException = ex;
  }
  finally
  {
   if (finalAction != null)
   {
    finalAction();
   }
  }

  ValidateThrownException(actualException, asserts);
 }

 /// 
 /// Valdidates the exception
 /// 
 /// Exception type to look for
 /// Exception to validate
 /// Additional asserts to be made on the exception
 private static void ValidateThrownException<T>(Exception actualException, Action<T> asserts) where T : Exception
 {
  if (actualException is T)
  {
   if (asserts != null)
   {
    asserts(actualException as T);
   }
  }
  else if (actualException == null)
  {
   throw new AssertFailedException(String.Format(
    "ExceptionAssert.Throws failed. No exception was thrown. Expected <{0}>.",
    typeof(T).FullName));
  }
  else
  {
   throw new AssertFailedException(String.Format(
    "ExceptionAssert.Throws failed. Expected <{0}>. Actual <{1}>",
    typeof(T).FullName,
    actualException.GetType().FullName));
  }
 }
}

Share:

Thursday, June 17, 2010

Variable number of arguments

The params keyword is very handy when you don't know the number of arguments is variable.
Note! No additional parameters are permitted after the params keyword.

// This method can take a variable number of ints
public int Sum(params int[] values)
{
  int sum = 0;
  foreach(int value in values)
  {
    sum += value;
  }
  return sum;
}

// Method calls
int sum1 = Sum(1, 2, 3, 4);
int sum2 = Sum(1, 2);

But be aware that this comes with a performance cost. When this method is called an array must be created, which is a costly operation.

If you know that your code for most of the time is calling this method with 3 arguments, then make a override with only three arguments. This method call is much quicker.
// Override with three params
public int Sum(int val1, int val2, int val3) { /* ... */ }
Share:

Wednesday, March 3, 2010

Comandline argument parser

Class that parses the commandline arguments.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace TestArgumentParser
{
    public class ArgumentParser
    {
        public string QuoteChars { get; set; }
        public string ValueSeparatorChars { get; set; }
        public string PrefixChars { get; set; }
        public Dictionary Params = new Dictionary();

        public string this[string key] { get{ return Params[key]; } }

        public ArgumentParser()
        {
            SetDefaultValues();
            string argString = GetComandLineArguments();
            Parse(argString);
        }

        public ArgumentParser(string args)
        {
            SetDefaultValues();
            Parse(args);
        }

        private static string GetComandLineArguments()
        {
            string argString = Environment.CommandLine;
            argString = argString.Replace("\"" + Process.GetCurrentProcess().MainModule.FileName + "\"", "");
            return argString;
        }

        public void Parse(string arguments)
        {
            string currentParam = string.Empty;
            string currentValue = string.Empty;
            bool readingParam = false;
            bool readingValue = false;
            bool startQuotes = false;
            foreach (char c in arguments)
            {
                if (IsPrefix(c))
                {
                    HandlePrefix(Params, ref currentParam, ref currentValue, ref readingParam);
                    continue;
                }
                if (readingParam)
                {
                    HandleParam(ref currentParam, ref readingParam, ref readingValue, c);
                    continue;
                }
                if (readingValue)
                {
                    HandleValue(ref currentValue, ref startQuotes, c);
                    continue;
                }

            }
            if (!string.IsNullOrEmpty(currentParam))
            {
                Params.Add(currentParam, currentValue);
            }
        }

        private void SetDefaultValues()
        {
            QuoteChars = "\"\'";
            ValueSeparatorChars = ":= ";
            PrefixChars = "-/";
        }

        private void HandlePrefix(Dictionary list, ref string currentParam, ref string currentValue, ref bool readingParam)
        {
            if (!string.IsNullOrEmpty(currentParam))
            {
                list.Add(currentParam, currentValue);
            }
            currentParam = string.Empty;
            currentValue = string.Empty;
            readingParam = true;
        }

        private void HandleValue(ref string currentValue, ref bool startQuotes, char c)
        {
            if (IsQuote(c))
            {
                startQuotes = !startQuotes;
                return;
            }
            if (!startQuotes && char.IsWhiteSpace(c))
            {
                return;
            }
            currentValue += c;
        }

        private void HandleParam(ref string currentParam, ref bool readingParam, ref bool readingValue, char c)
        {
            bool isValueSeparator = IsValueSeparator(c);
            if (!isValueSeparator)
            {
                currentParam += c;
            }
            else
            {
                readingValue = true;
                readingParam = false;
            }
        }

        private bool IsQuote(char c)
        {
            return QuoteChars.IndexOf(c) > -1;
        }

        private bool IsValueSeparator(char c)
        {
            return ValueSeparatorChars.IndexOf(c) > -1;
        }

        private bool IsPrefix(char c)
        {
            return PrefixChars.IndexOf(c) > -1;
        }
    }
}

Share:

Monday, February 22, 2010

Expression trees

Howto get the name of a property or class. To minimize magic strings

Usage:
// This code will return "MyProperty".
ObjectHelper.GetMemberName(() => someEntity.MyProperty);

        using System;
using System.Linq.Expressions;
/// 
/// Extensions to object class
/// 
public static class ObjectHelper
{
/// 
/// Gets the name og the property og class using Expression trees
/// 
/// 
/// The expression to get name for
/// 
/// 
/// Type of the object
/// 
/// 
/// A string with the name, or an exception if it isn't a member expression
/// 
/// 
/// 
private static string GetMemberName(Expression> e)
{
var member = e.Body as MemberExpression;
// If the method gets a lambda expression
// that is not a member access,
// for example, () => x + y, an exception is thrown.
if (member == null)
{
throw new ArgumentException(
"'" + e +
"': is not a valid expression for this method");
}
return member.Member.Name;
}
}
Share:

Wednesday, November 25, 2009

C# ?? Operator

The null-coalescing operator is a great way to save space in your code.

// if ObjectThatCouldBeNull is null then print out the default text
// otherwise print the object value

if(ObjectThatCouldBeNull != null)
{
 Console.WriteLine("{0}", ObjectThatCouldBeNull);
}
else
{
 Console.WriteLine("Value is null");
}

// a better way
Console.WriteLine("{0}", ObjectThatCouldBeNull != null ? ObjectThatCouldBeNull : "Value is null");

// a even better way
Console.WriteLine("{0}", ObjectThatCouldBeNull ?? "Value is null");


sweet :-)
Share: