Stack Exchange
Using reflection to set an interface member
I'm having trouble setting the value of a property in a class when the property type is and interface using PropertyInfo.SetValue.
This code is for unit testing which I'd like to use to fake out the IDbSets in my Entity.
public static void AddFakeDbSets<T>(this Mock<T> obj) where T : class
{
    var iDbSets = typeof(T).GetProperties().Where(p => 
        p.PropertyType.IsGenericType == true &&
        p.PropertyType.GetGenericTypeDefinition().Name.StartsWith("IDbSet"));

    Type baseType = typeof(FakeDbSet<>);

    foreach (var iDbSet in iDbSets)
    {
        if (iDbSet.GetValue(obj.Object) == null)
        {
            var genericType = baseType.MakeGenericType(iDbSet.PropertyType);
            var concreteObject = Activator.CreateInstance(genericType);
            iDbSet.SetValue(obj.Object, concreteObject);
        }
    }
}

Specifically it crashes at iDbSet.SetValue() with the following error:

Object of type
  'lnEcommAPI.Tests.FakeDbSet1[System.Data.Entity.IDbSet1[LNWebServicesRepository.WhatsNew]]'
  cannot be converted to type
  'System.Data.Entity.IDbSet`1[LNWebServicesRepository.WhatsNew]'.


For future readers: Answer fixes the crash, but Moq still gets in the way of assigning the value.

My guess: replace
var genericType = baseType.MakeGenericType(iDbSet.PropertyType);

by
var genericType = baseType.MakeGenericType(iDbSet.PropertyType.GetGenericArguments()[0]);

The problem is that iDbSet.PropertyType is equal to IDbSet<XXX>.
Thus, typeof(FakeDbSet<>).MakeGenericType(iDbSet.PropertyType) creates a FakeDbSet<IDbSet<XXX>>, while you're expecting a FakeDbSet<XXX>

Excellent catch, it no longer crashes but the property does not get set either. Kind of a head-scratcher, I was thinking it had something to do with Moq, but that shouldn't be a problem.

In this case, it's not the same problem !

Your property setter may be empty for instance... try to inspect iDbSet.GetGetMethod().GetMethodBody().GetILAsByteArray().Length ... if it's less than 4 bytes long, then your setter does nothing :)

Cool trick; GetMethodBody is 11 bytes and SetMethodBody is 8.

Additionally the following code does not set the property either: var setter = iDbSet.GetSetMethod(); var result = setter.Invoke(obj.Object, new [] { concreteObject });

8 & 11 is very likely to be a traditional automatic get/set property with a field ... could you copy/paste iDbSet.GetSetMethod().GetMethodBody().GetILAsByteArray() bytes here ?

Let us continue this discussion in chat.
