简体   繁体   中英

Generic method for creating Mock<interface> by Moq

I am trying to create some abstract class which will keep some common operation for preparing Stubs by Moq. I wrote something but I cannot overcome errors

public abstract class StubsCreatorAbstract
{
    public Mock<T> GenerateObject<T>() where T : IStub
    {
        var mock = new Mock<T>();
        return mock;
    }

    public Mock<D> SetupValue<T, D>(Mock<D> stub, string nameOfField, T value) where D : IStub
    {
        var field = typeof(D).GetProperty(nameOfField);
        if (field == null)
        {
            throw new ArgumentException("Field do not exist");
        }

        field.SetValue(stub.Object, value);
        return stub;
    }
 }

The problems is: Mock must be a reference type. My question is - it's possible to overcome that problem? Thanks in advance

Update:

That's compiler error. Problem regarding to T - it's saying

"the type 'T' must be a reference type in order to use it as parameter 'T' in the generic type or method 'Mock<T>".

The short answer is that:

public Mock<T> GenerateObject<T>() where T : IStub
{
    var mock = new Mock<T>();
    return mock;
}

won't work. Instead you should use:

new Mock<YourTypeHere>();

instead.

As to why your original code doesn't work, I've done a bit of research but I am not 100% sure why.

It seems like you are using a non reference type as the generic constraint. I believe IStub is the interface that is being implemented in the concrete class that you are using. if you specify the constraint like below, it will work fine.

If you want more specific constraint, let your classes inherit from a base class and give that as the constraint here.

 public abstract class StubsCreatorAbstract
{
    public Mock<T> GenerateObject<T>() where T : class 
    {
        var mock = new Mock<T>();
        return mock;
    }

    public Mock<D> SetupValue<T, D>(Mock<D> stub, string nameOfField, T value) where D : class
    {
        var field = typeof(D).GetProperty(nameOfField);
        if (field == null)
        {
            throw new ArgumentException("Field do not exist");
        }

        field.SetValue(stub.Object, value);
        return stub;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM