Mocking generic methods in Moq without specifying T

后端 未结 6 744
我在风中等你
我在风中等你 2020-12-03 00:45

I have an interface with a method as follows:

public interface IRepo
{
    IA Reserve();
}

I would like to mock the clas

6条回答
  •  一整个雨季
    2020-12-03 01:09

    Here's one way to do it which seems to work. If all the classes you're using in IRepo inherit from a single base class you can use this as-is and never have to update it.

    public Mock SetupGenericReserve() where TBase : class
    {
        var mock = new Mock();
        var types = GetDerivedTypes();
        var setupMethod = this.GetType().GetMethod("Setup");
    
        foreach (var type in types)
        {
            var genericMethod = setupMethod.MakeGenericMethod(type)
                .Invoke(null,new[] { mock });
        }
    
        return mock;
    }
    
    public void Setup(Mock mock) where TDerived : class
    {
        // Make this return whatever you want. Can also return another mock
        mock.Setup(x => x.Reserve())
            .Returns(new IA());
    }
    
    public IEnumerable GetDerivedTypes() where T : class
    {
        var types = new List();
        var myType = typeof(T);
    
        var assemblyTypes = myType.GetTypeInfo().Assembly.GetTypes();
    
        var applicableTypes = assemblyTypes
            .Where(x => x.GetTypeInfo().IsClass 
                    && !x.GetTypeInfo().IsAbstract 
                     && x.GetTypeInfo().IsSubclassOf(myType));
    
        foreach (var type in applicableTypes)
        {
            types.Add(type);
        }
    
        return types;
    }
    

    Otherwise, if you don't have a base class you can modify the SetupGenericReserve to not use the TBase type parameter and instead just create a list of all the types you want to set up, something like this:

    public IEnumerable Alternate()
    {
        return new [] 
        {
            MyClassA.GetType(),
            MyClassB.GetType()
        }
    }
    

    Note: This is written for ASP.NET Core, but should work in other versions except for the GetDerivedTypes method.

提交回复
热议问题