moq icon indicating copy to clipboard operation
moq copied to clipboard

Generic method setups of parent types invoked

Open rkkr opened this issue 6 months ago • 0 comments

Describe the Bug

We want to test a generic function that has multiple invocations of related types. In the test below exception Unable to cast object of type 'Foo' to type 'Bar' is thrown at line mock.Object.Create<Bar>() because x.Create<Foo> setup was invoked. mock.Object.Create<Foo>() also invokes x.Create<Foo>.

Steps to Reproduce

    public class Foo;
    public class Bar : Foo { };

    public interface ICreator 
        {
        T Create<T> ();
        }

    [TestClass]
    public class Test
        {
        [TestMethod]
        public void WrongSetup ()
            {
            var mock = new Mock<ICreator>(MockBehavior.Strict);

            mock.Setup(x => x.Create<Bar>()).Returns(new Bar());
            mock.Setup(x => x.Create<Foo>()).Returns(new Foo());
            
            var bar = mock.Object.Create<Bar>();
            }
        }

Expected Behavior

Default generics setup behavior seems to work like It.IsSubtype<T>. It should default to strict match. If loose match is needed It.IsSubtype<T> can be used.

Exception with Stack Trace

ICreatorProxy.Create[T]()
Test.WrongSetup() line 32
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Version Info

4.20.70

Additional Info

Setups can be reversed to make the test pass as child setup is then matched first, but this is not a usable workaround.

Back this issue Back this issue

rkkr avatar Aug 23 '24 12:08 rkkr