The combination of Moq and Equals (), parsing the structure of MS Testing

I have what I think should be a very simple test case, but every time I run it, QTAgent32 dies. Running a test case in debug mode shows that System.StackOverflowException"Unknown module" is selected. I narrowed it down to the most basic implementation that demonstrates this behavior (.NET 4 and VS 2010 Ultimate):

[TestClass]
public class StackOverflow
{
    [TestMethod]
    public void CreateStackOverflow()
    {
        var mockMyType1 = new Mock<MyType>();
        mockMyType1.Setup(m => m.Equals(mockMyType1.Object)).Returns(true);

        var mockMyType2 = new Mock<MyType>();

        // Real test is for a filtering routine and the Assert is using
        // Contains(), but it uses Equals() internally so it has the same problem
        Assert.IsTrue(mockMyType1.Object.Equals(mockMyType1.Object)); // returns true
        Assert.IsFalse(mockMyType1.Object.Equals(mockMyType2.Object)); // explodes
    }
}

public class MyType
{
    public virtual bool IsActive { get; set; }
    public override bool Equals(object obj)
    {
        return false;  // Not the real implementation but irrelevant to this issue
    }
}

I feel like I'm missing something important with regards to closing, or maybe Moka, but it seems like this should work. Things I tried trying to understand the problem, but only confused me more:

  • I tried replacing the Equals () setting with mockMyType.Setup(m => m.Equals(m)).Returns(true);, but that causes Moq to throw a NotSupportedException
  • If I make CallBase true instead of setting Equals (), everything works
  • , MyType Equals(), .

- , ? .

: , ( ), , . - Moq Visual Studio, ?

. Denys Moq. :

mockMyType1.Setup(m => m.Equals(It.Is<MyType>(x => ReferenceEquals(x, mockMyType1.Object)))).Returns(true);
+5
3

, , . , . ReferenceEquals. GetMockMyTypes. , , , :

public static class MyTypeHelper
{
   public static IList<MyType> GetMockMyTypes()
   {
      var myTypes = new List<MyType>();

      var myMock1 = new Mock<MyType>().Object;
      Mock.Get(myMock1)
          .Setup(m => m.Equals(It.Is<MyType>(x => ReferenceEquals(x, myMock1))))
          .Returns(true);
      Mock.Get(myMock1).Setup(m => m.IsActive).Returns(false);
      myTypes.Add(myMock1);

      var myMock2 = new Mock<MyType>().Object;
      Mock.Get(myMock2)
          .Setup(m => m.Equals(It.Is<MyType>(x => ReferenceEquals(x, myMock2))))
          .Returns(true);
      Mock.Get(myMock2).Setup(m => m.IsActive).Returns(true);
      myTypes.Add(myMock2);

      return myTypes;
   }
}
+1

, Equals (), ( Reflector/dotPeek, ):

MOQ Stackoverflow

- . Equals MyType, Equals(MyType) Equals(object):

    public virtual bool Equals(MyType obj)
    {
        return Equals((object)obj);
    }
+3

, , :

mockMyType.Setup(m => m.Equals(mockMyType.Object)).Returns(true);

. - , .

:

mockMyType.Setup(m => m.Equals(It.IsAny<MyType>())).Returns(true);

.

+1
source

All Articles