What a Moqery…

Every new technology that comes into a developer’s hand goes through a so called “honeymoon period”. I’ve been hooked onto Moq these days. I am quite sure down the line, few years pass by and I shall be using something more "usable” than Moq and would consider that as my best mocking tool. But that is just another page in a developer’.

Back to the meat of this blog, the other day I was mocking certain classes for writing some behavioural tests. There was a reason to mock certain properties of a class. For Moq to mock the property it has to be marked as virtual. Ideally, I would have it part of an interface that can be mocked with Moq. But that is a different topic all together. To put forward my point, look at the below code snippet of a pretty dumb method “DeReplace”. All it does is for the string stored in BarProperty, it replaces ‘a’ with ‘@’.

private string bar;
public virtual string BarProperty { get { return bar; }set { bar = value; } }

public string DoReplace()
{
if(String.IsNullOrEmpty(bar))
{
throw new InvalidOperationException("The bar string cannot be null or empty.");
}
return bar.Replace('a', '@');
}


One heck of a useful method eh! This is a test for the above method using Moq,



[TestMethod]
public void TestBarStuff()
{
var mockBar = new Moq.Mock();
mockBar.SetupGet(x => x.BarProperty).Returns("skadoosh!!!");
var result = mockBar.Object.DoReplace();
Assert.AreEqual("sk@doosh!!!", result);
}


Did it work. Of course not. It resulted in the InvalidOperationException and the assertion failed. Why? We did setup the BarProperty correctly with Moq, but what are we using in our original method? We are using bar string. This does bring back the discussion whether to use properties for local usages or just use local member variables. I shall leave that discussion for StackOverflow, but one thing is pretty clear. If you intend to mock properties for a class, you better use them in your methods. Below is the changed class to make the test work,



private string bar;
public virtual string BarProperty { get { return bar; }private set { bar = value; } }

public string DoReplace()
{
if(String.IsNullOrEmpty(BarProperty))
{
throw new InvalidOperationException("The bar string cannot be null or empty.");
}
return BarProperty.Replace('a', '@');
}

Ahh that green color, sweet.

Happy “Moq”ing.

Abhang Rane


Some “Moq”ing

I have become a big fan of Moq since I started using it. The reason I like it so much is its ease of use. I have not bothered to learn Rhino Mocks or NMock for that matter coz since I have started using it, its the 3rd team I have joined for a project where they have choosen Moq over all others.

Right, back to work. Did you ever have a requirement where you had to mock some methods of a class and leave out certain methods as is? Consider that following utterly useless classes,

public class Foo
{
public string CallMe()
{
var result = DoSomethingImportant();
return result.ToString();
}
public virtual int DoSomethingImportant()
{
return 10000;
}
}

public class Bar : Foo
{
}

Ya they are pretty dumb I know. The point is this, say you would like to mock the Bar class and test out its CallMe method. This is how it might look,

[TestMethod]
public void TestBarStuff()
{
var mockBar = new Moq.Mock();
var result = mockBar.Object.CallMe();
Assert.AreEqual("10000", result);
}

You run this test and you meet this error,

image


The problem here is, you sure have a virtual method in Foo, but there is no overridden implementation provided in Bar. Moq underneath derives from the target class (in this case Bar) and injects its setup implementations for the virtual members as provided. Although, if you intend to leave a method in the base class (Foo) as is, you need to tell Moq to do so. Common it can’t be that smart! To do this, use the “CallBase” property on the mock object. This does exactly what it says and calls the base virtual implementation in case a setup is not matched. Below is the working test for the same,

[TestMethod]
public void TestBarStuff()
{
var mockBar = new Moq.Mock();
mockBar.CallBase = true;
var result = mockBar.Object.CallMe();
Assert.AreEqual("10000", result);
}

Now run the test again. I just love when I see that green color, dont you!

Happy Moqing!

Abhang Rane