0

I have a test that find all class that inherited from BaseClass. BaseClass has a property with a method that use generics:

abstract class BaseClass 
{
   public MyTools Tools { get; set;}

   public abstract List<TEntity> GetAll();

   public virtual IList<TEntity> Convert<TEntity, TEntityOther>() 
   {
       //...
   }
}

class MyTools 
{
   IList<T> List<T>();    
}

Then, I need to mock the T List<T>() method. The method is used in Create method. For example:

class MyClass: BaseClass<MyEntity>
{
    public override List<MyEntity> GetAll()
    {
        var x = this.MyTools.List<SomeClass>();

        return this.Convert<MyEntity, SomeClass>(x);
    }
}

I don't know what type is used within GetAll to call List method.

This is my test:

var xobjects = this.GetTypeInNamespace(myAssembly, typeof(BaseClass<>));

foreach(var obj in xobjects) 
{
   var myTools  = new Mock<MyTools>();

   //here is my problem
   myTools.Setup(x => x.List< ANY >()).Returns(new List< ANY >());

   var iobj = this.CreateInstance(obj);

   iobj.MyTools = myTools.Object;  

   var result = iobj.GetType().GetMethod("GetAll").Invoke(iobj, null);

   ((ICollection)result).Count.Should().Be(0);
}

How I can setup the method List <T> for any T?

I don't know what type is T and I do not care what type it is.

andres descalzo
  • 14,887
  • 13
  • 64
  • 115
  • Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the [How to Ask](http://stackoverflow.com/help/how-to-ask) page for help clarifying this question. – Nkosi Oct 31 '16 at 19:23
  • @Nkosi ready, I added more details – andres descalzo Oct 31 '16 at 19:36
  • this example method is still confusing `this.Convert(x);` – Nkosi Oct 31 '16 at 20:09
  • `List()` returns an instance of `T` or a an instance of `List`? The naming is confusing when compared to what it is suppose to return. – Nkosi Oct 31 '16 at 20:32
  • @Nkosi yes, you are right. I fixed it. `List` return a list of `T`. The application is big, I extracted a part of that. That was my mistake – andres descalzo Oct 31 '16 at 22:06
  • There are too many inconsistencies in this question which only leads to guessing what the problem is. Provide a [mcve] that reproduces the problem. – Nkosi Oct 31 '16 at 22:40
  • 1
    Related to [Mocking generic method call for any given type parameter](http://stackoverflow.com/questions/5311023/). – Jeppe Stig Nielsen Oct 31 '16 at 23:06
  • Is `MyTools` a class (as shown) or an interface? If it is a class, the declaration of the generic method you are trying to mock is not precise enough. Is it a `virtual` method? – Jeppe Stig Nielsen Oct 31 '16 at 23:08
  • @JeppeStigNielsen MyTools is a interface in my real project. The method `List` is not virtual, and I need mock for any type. – andres descalzo Nov 02 '16 at 17:24
  • @JeppeStigNielsen in the answer http://stackoverflow.com/questions/5311023/mocking-generic-method-call-for-any-given-type-parameter they know the type, in the explame is `ATable`, but I don't know the type and I don't matter the type – andres descalzo Nov 02 '16 at 17:27
  • 1
    Does the interface `MyTools` contain many other members, besides the generic method in question, in the "real project"? Because if this is hard to do with Moq, maybe it is easy to just write a dummy class that implements the interface, and inject that, instead of using Moq. – Jeppe Stig Nielsen Nov 02 '16 at 20:06
  • @JeppeStigNielsen yes, it is a good solution, I'm working with that, the problem is that I have 30+ method in `MyTools` interface – andres descalzo Nov 03 '16 at 14:35
  • This is not really supported by Moq. You can change to `var myTools = new Mock { DefaultValue = DefaultValue.Mock, };` and not make any Setup on the method in question. Then the loose mock will create a "recursive" mock when the method is invoked. This will be a proxy class that inherits from `List`. This is possible because `List<>` is not sealed and has an accessible zero-parameter constructor. This "next-level" mock will act just like an empty `List<>`. Note: There are no `virtual` methods/properties on `List<>`, so Moq's deriving class will be just like `List<>`. – Jeppe Stig Nielsen Nov 04 '16 at 09:34
  • @JeppeStigNielsen finally, I implemented your propose "maybe it is easy to just write a dummy class that ...". Can you add an answer? – andres descalzo Nov 12 '16 at 14:11

1 Answers1

0

I'm aware the question is 3 years old, but since moq 4.13 it is possible to specify It.IsAnyType for generic type matching.

riezebosch
  • 1,950
  • 16
  • 29