Tech Tock

Time is of the essence.

Freakin’ Moq

While I, like many developers,  appreciate Moq immensely, its not perfect.

Here’s an interesting way to freak out Moq 3.1:

It seems that if you use a 2 dimensional array as a parameter (a common scenario in fixed income) Moq will throw an error when accessing the Moq’d object.

This code:

public interface IFreakOutMoq { void FooBar(string[,] Strings); }

var badMock = new Mock<IFreakOutMoq>();
var badMockObj = badMock.Object;   //exception here

Will throw one of these exceptions (I’ve seen both on different systems):

System.TypeLoadException: System.TypeLoadException: Signature of the body and declaration in a method implementation do not match.

System.TypeLoadException: Method ‘FooBar’ does not have an implementation..

A simple solution is to use a Moq friendly object instead of the 2D array:

public class TwoDArray<T> {
private readonly T[,] _array;

public TwoDArray(T[,] array)     {    _array = array;     }

public T this[int x, int y]     {         get { return _array[x, y]; }     }
public T[,] Array     {         get { return _array; }     }   }
}

Here’s a test class that shows a working and failing example:

using System; using System.Text; using System.Collections.Generic; using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using TestProject;   namespace TestProject {   /// <summary> /// an array implementation that doesn't ///     freak Moq out on MockObj.Obj /// /// if you put a 2d array as a param and call mockedObj.Object /// moq will throw exception: ///     System.TypeLoadException: System.TypeLoadException: ///             Signature of the body and declaration ///             in a method implementation do not match. ///     or  System.TypeLoadException: Method 'FooBar' ///             does not have an implementation.. /// /// this object can be used instead and moq is fine /// </summary> /// <typeparam name="T"></typeparam> public class TwoDArray<T> {
private readonly T[,] _array;       public TwoDArray(T[,] array)     {         _array = array;     }
public T this[int x, int y]     {         get { return _array[x, y]; }     }
public T[,] Array     {         get { return _array; }     }
}   }
/// <summary> /// mocking this interface causes: /// System.TypeLoadException: ///         Method 'FooBar' in type ///         'IFreakOutMoqProxy2dec23fc008646958fc3bae70cbe067b' ///         does not have an implementation.. /// </summary> public interface IFreakOutMoq { void FooBar(string[,] Strings); }     public interface IMoqOK { void FooBar(TwoDArray<string> Strings); }   /// <summary> /// Summary description for UnitTest1 /// </summary> [TestClass] public class UnitTest1 {   [TestMethod] public void TestMethod1() {
var goodMock = new Mock<IMoqOK>();
var mockObj = goodMock.Object;
var badMock = new Mock<IFreakOutMoq>();
var badMockObj = badMock.Object; //exception will be thrown here
Assert.IsNotNull(mockObj);
Assert.IsNotNull(badMockObj);   } }
Advertisements

September 9, 2010 - Posted by | Uncategorized | , , ,

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: