A collection of learnings and opinions.

Showing posts with label properties. Show all posts
Showing posts with label properties. Show all posts

Thursday, September 24, 2009

Mocking expectations on Property setters with MoQ

When mocking out your classes using the fabulous MoQ mocking-framework you may sometimes need to mock out an expectation that a property on your mocked object should be set.

It took me some time to figure out how to do this. The documentation on the MoQ quickstart wiki says to use the following pattern:

// expects an invocation to set the value to "foo"
mock.SetupSet(foo => foo.Name = "foo");


Well, I tried this with an object:

public class SomeClass {
public string Something { get; set; }
}

[Test]
public void PropertySetupOnMock() {
const string someString = "Should be set";
var mocker = new Mock<SomeClass>();

mocker.SetupSet(x => x.Something = someString); //exception here
mocker.Object.Something = someString;
mocker.VerifySet(x => x.Something);
}

This only gave me an error on the line with the SetupSet:
System.ArgumentException: Invalid expectation on a non-overridable member.

Well, that's strange. After some looking around it turns out that MoQ does its magic by extending the class that's being mocked. It cannot extend non-virtual properties, so this Something property cannot be extended and thus cannot be Setup.
What can be done about this? The easiest immediate solution would be to mark the property virtual, like so:

public class SomeClass {
public virtual string Something { get; set; }
}

But do we really want to decorate every property on the objects as virtual? Not really. A better solution is to push the property up to an interface and mock that interface instead, like so:

public interface IWithProperty {
public string Something { get; set; }
}

public class SomeClass : IWithProperty {
public string Something { get; set; }
}

[Test]
public void PropertySetupOnInterfaceMock() {
const string someString = "Should be set";
var mocker = new Mock<IWithProperty>();

mocker.SetupSet(x => x.Something = someString); //no exception here
mocker.Object.Something = someString;
mocker.VerifySet(x => x.Something);
}

Thus allowing me to mock it out and test that the property setter was indeed called. Yay!
If anyone has any better ways of doing this I'd love to hear from you!

Tuesday, February 10, 2009

Listing the properties of an object

Sometimes you just want to print out the state of some reasonably rich object (for logging or GUI mock-up or whatever). This code gives you a PropertyGetter class with two easy-to-use static methods. listProperties returns a name: value string listing of the properties on the input object, for easy logging.

If you want the object's properties as a list of properties you can get that as well.

NB: This simple class does not recurse through complex objects, so you will only ever get the top-level of a property.

Code:

using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Code_Examples {
class PropertyGetter {
public static string listProperties(object someObject) {
StringBuilder sb = new StringBuilder();

List<pair> props = getProperties(someObject);

foreach (Pair prop in props) {
sb.AppendLine(prop.Name + ": " + prop.Value);
}
return sb.ToString();
}

public static List<pair> getProperties(object someObject) {
List<pair> dic = new List<pair>();

PropertyInfo[] props = someObject.GetType().GetProperties();
foreach (PropertyInfo prop in props) {
Pair t = new Pair {
Name = prop.Name,
Value = prop.GetValue(someObject, null)
};
dic.Add(t);
}
return dic;
}
}

public class Pair {
public string Name {
get;
set;
}
public object Value {
get;
set;
}
}
}