views:

84

answers:

2

I've got a couple of methods that use reflection to transform from one object type to another. I'm in the process of testing the transformation methods via Moq and have stumbled upon a behavior I don't know how to handle. When I reflect across a Moq object to obtain PropertyInfo's, I get two additional objects.

  • Moq.Mock``1[Namespace.Class+IElement] Mock
  • Moq.Mock Mock

The code to reproduce this is below:

public void Moq_Reflection() {
    var realElement = new Stuff();

    // Produces 2 items
    PropertyInfo[] pInfo = realElement.GetType().GetProperties(); 

    var mockElement = new Mock<IElement>();
    mockElement.Setup(e => e.Property1).Returns(12);
    mockElement.Setup(e => e.Property2).Returns(42);

    // Produces 4 items
    pInfo = mockElement.Object.GetType().GetProperties();
}

public interface IElement { 
    int Property1 { get; set; } 
    int Property2 { get; set; } 
}

public class Stuff : IElement
{
    public int Property1
    {
        get { return -1; }
        set { }
    }

    public int Property2
    {
        get { return -2; }
        set { }
    }
}

Is there a way to Reflect on a Moq object and not retrieve these properties?

A: 

I took a look at the code in LinqPad, and the only solution I could find to cut those two properties out was to exclude them based on whether PropertyType or Name included "Mock". For example:

pInfo.Where(item => item.PropertyType.ToString().Contains("Mock") == false);
pInfo.Where(item => item.Name.Contains("Mock") == false);

It's borderline hacky, but it's the only attribute I can find to filter. I don't think there's a way to filter the reflection itself.

Darren
I was hoping it wouldn't have to be that way. There's nothing uglier than writing code in your main app to compensate for your tests. Thanks though, I appreciate the help!
Gavin Miller
+1  A: 

I was thinking about this more this afternoon, so here's another idea.

If I were coding this in my own project, I'd abstract out the reflection of the object. I'd create an interface that defines a contract for a class that will return the properties of an object, and then create a class that implements that interface by using reflection to return the set of properties. Same as what you're probably doing.

But then in the tests, I'd create a new implementation of the interface, but I'd add in whatever rules I needed to filter out unwanted properties on my mock objects. My live code wouldn't include any of the code necessary for testing.

I just had to get that idea out, just trying to help. Good luck!

Darren