Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mock.Of<T> fails with exception 'Unhandled Exception: System.ArgumentException: Interface not found' #340

Closed
kichalla opened this issue Apr 20, 2017 · 3 comments
Labels

Comments

@kichalla
Copy link

Moq version: 4.7.8

Error:

Unhandled Exception: System.ArgumentException: Interface not found.
   at System.RuntimeTypeHandle.VerifyInterfaceIsImplemented(RuntimeTypeHandle handle, RuntimeTypeHandle interfaceHandle)
   at System.RuntimeType.GetInterfaceMap(Type ifaceType)
   at Moq.Extensions.IsGetObjectDataVirtual(Type typeToMock)
   at Moq.Extensions.IsSerializableMockable(Type typeToMock)
   at Moq.SerializableTypesValueProvider.ProvideDefault(MethodInfo member)
   at Moq.Mock.GetInitialValue(IDefaultValueProvider valueProvider, Stack`1 mockedTypesStack, PropertyInfo property)
   at Moq.Mock.SetupAllProperties(Mock mock, Stack`1 mockedTypesStack)
   at Moq.Mock.<>c__DisplayClass72_0.<SetupAllProperties>b__0()
   at Moq.PexProtector.Invoke(Action action)
   at Moq.Mock.SetupAllProperties(Mock mock)
   at Moq.Mock`1.SetupAllProperties()
   at Moq.Mocks.<CreateMocks>d__6`1.MoveNext()
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at Moq.Linq.MockQueryable`1.Execute[TResult](Expression expression)
   at Moq.Mock.Of[T]()
   at moq_repro.Program.Main(String[] args)

Repro1

    class Program
    {
        static void Main(string[] args)
        {
            var mock = Moq.Mock.Of<Test>();
        }
    }

    public abstract class Test
    {
        public abstract System.Security.Claims.ClaimsPrincipal Principal { get; }
    }

Repro2

    class Program
    {
        static void Main(string[] args)
        {
            var mock = Moq.Mock.Of<Test>();
        }
    }

    public abstract class Test
    {
        public abstract Foo FooProperty { get; }
    }

    [Serializable]
    public class Foo
    {
        public Foo()
        {

        }

        protected Foo(SerializationInfo info, StreamingContext context)
        {

        }
    }
@pranavkm
Copy link

Perhaps https://github.com/moq/moq4/blob/c8c5db1775c6b6a9e682e34f14bf7b79782b70de/Source/Extensions.cs#L178 should check if a type implements ISeriablizable before it invokes GetInterfaceMap.

@stakx
Copy link
Contributor

stakx commented Jun 4, 2017

My current understanding of (binary) serialization in .NET is that it follows these rules:

  • A type is recognized as serializable only if it is marked with a [Serializable] custom attribute. The presence or absence of ISerializable in the list of implemented interfaces doesn't matter at all.
  • The deserialization constructor .ctor(SerializationInfo info, StreamingContext context) is used by formatters only if the type implements ISerializable.
  • The method void GetObjectData(SerializationInfo info, StreamingContext context) is used by formatters only if the type implements ISerializable.

I haven't yet investigated what Moq did or did not do in previous versions, but based on the above, I believe it should do the following:

  • The serializable type in repro 1 (ClaimsPrincipal) has a GetObjectData method, but it does not implement ISerializable; so GetObjectData should be ignored.
  • The serialitable type in repro 2 (Foo) has a deserialization constructor, but it does not implement ISerializable; so the deserialization constructor should be ignored.

Does that sound right?

@pranavkm
Copy link

pranavkm commented Jun 5, 2017

@stakx based on the remarks in https://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx, your summary seems correct:

Any class that might be serialized must be marked with the SerializableAttribute

More interestingly, as part of a recent PR, they identify ClaimsPrincipal as being a non-serializable type: dotnet/corefx#20220 even though it implements ISerializable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants