1

I'm trying to implement a unit test with Moq that needs to be able to mock an interface that comes from a COM library. Specifically, I need Moq to recognize that an object of type Point is actually a Point when calling a method that takes type Point as a parameter. This Point type is from an ESRI ArcGIS library. However, even when doing what seems to be a very simple test, I get the invocation failed exception because the call didn't match a setup. Here is the simplest case I can make:

public interface ITest
{
    int TestMethod(Point p);
}

public class TestClass : ITest
{
    public int TestMethod(Point p)
    {
        return 0;
    }
}

[TestMethod]
public void MyTest()
{
    Mock<ITest> mockTest = new Mock<ITest>(MockBehavior.Strict);
    mockTest.Setup(x => x.TestMethod(It.IsAny<Point>())).Returns(0);
    mockTest.Object.TestMethod(new Point());
}

When I call TestMethod, I get the exception. If I look at the type of Point during the run, the type is System.__ComObject, which I can't directly create due to protection level. When I look at the metadata for Point, here's what I see:

using System.Runtime.InteropServices;

namespace ESRI.ArcGIS.Geometry
{
    [CoClass(typeof(PointClass))]
    public interface Point : IPoint
    {
    }
}

I also tried mocking IPoint instead and there was no difference. Is there any way to get Moq to recognize a new Point() in the Setup method? I would even be ok with a way to tell Moq, "Hey, I don't care what any of the passed parameters are. ALWAYS return the specified return NO MATTER WHAT. NEVER return null." But it's starting to look like I'm out of luck here.

C. Williamson
  • 319
  • 3
  • 13
  • Stretching the bounds of possibility, but have you tried `Setup(x => x.TestMethod(It.IsAny())).Returns(0);` ? – stuartd Aug 26 '16 at 17:14
  • Yes, I attempted that. __ComObject is inaccessible due to protection level. Maybe there's a way around that? Not sure. – C. Williamson Aug 26 '16 at 17:17
  • 2
    I've sort of worked around this by making a wrapper class for Point and then having Moq setup with the wrapper class instead. However, this isn't ideal because it requires me to modify the business logic to use the wrapper class. Hoping somebody has a better suggestion. – C. Williamson Aug 26 '16 at 18:49
  • 1
    Wrapper classes and unit tests seem to go together – stuartd Aug 26 '16 at 21:06
  • 1
    @C.Williamson, I would say go down the route or using types you own and control as `Point` and it's related components would be considered 3rd party dependency details which should be abstracted away. The issues you are currently having with it is also a clear indicator of it's impact on your design. – Nkosi Aug 27 '16 at 00:43

0 Answers0