lundi 5 juin 2017

Generics with runtime Types

I am using Moq and want to mock an interface which inherits from ICloneable. I am using Newtonsoft.Json to serialise and deserialise my object to a cloned instance.

The interface:

 public interface ITestInterface : ICloneable
 {
     int Number { get; set; }
     string Text { get; set; }
     string MethodCallResult { get; set; }
     void CallMe();
 }

I am trying to use generics to convert the object but I cannot know the actual runtime type of the proxy which Moq will provide.

Using the debugger through the following method I can see that the runtime type is a proxy but the type of the generic 'T' is the interface, ITestInterface, which cannot be serialised. How can I use the real runtime type with generics to serialize/deserialize these objects? I would just pass the type as a parameter but I do not know it at compile time.

private object CreateClone<T>(T item)
        where T : class
    {
        var realRuntimeType = item.GetType(); //is a proxy created by Moq inheriting from the interface
        var itemAsSerializedString = JsonConvert.SerializeObject( item );
        return JsonConvert.DeserializeObject<T>( itemAsSerializedString ); //wont work, tries to instantiate interface
    }

Usage (note that the generic parameter is inferred, not explicit):

var mock = new Mock<ITestInterface>();
mock.Setup(m => m.Clone()).Returns(CreateClone(mock.Object));

Exception:

Newtonsoft.Json.JsonSerializationException : Could not create an instance of type Processus.Tests.ITestInterface. Type is an interface or abstract class and cannot be instantiated.





Aucun commentaire:

Enregistrer un commentaire