This post shows howto to make your extension methods mockable..
http://www.clariusconsulting.net/blogs/kzu/archive/2009/02/19/Makingextensionmethodsamenabletomocking.aspx
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.
How I solved this earlier was to make a testable class that inherited from the class I wanted to test.
I now could do the following.
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.
_accessor" that you can use in your tests. My example from above can now be rewritten to the following:
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.
- Goto the ClassUnderTest in visual studio and right click. Select "Create Private Accessor" and select the test project you want this accessor in.
- 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".
[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
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:
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.
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.
The source code for the helper class can be found below.
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)); } } }
Wednesday, September 15, 2010
ASP.NET LIVE: jQuery dialog extender for Asp.Net MVC Views
A good example of using the dialog in JQuery UI with ajax.
ASP.NET LIVE: jQuery dialog extender for Asp.Net MVC Views
ASP.NET LIVE: jQuery dialog extender for Asp.Net MVC Views
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.
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.
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) { /* ... */ }
Monday, June 7, 2010
AD LDS for Windows 7
On XP machines there was a a service called ADAM that could be used when you needed a lightweight ActiveDirectory. This was extremely useful when developing applications that used AD. You could test your application without the need to modify your client/company AD.
But this service was not supported in Vista or Win7.
But now Microsoft have released AD LDS for Win7 that can be downloaded here:
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=a45059af-47a8-4c96-afe3-93dab7b5b658
But this service was not supported in Vista or Win7.
But now Microsoft have released AD LDS for Win7 that can be downloaded here:
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=a45059af-47a8-4c96-afe3-93dab7b5b658
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; } } }