Интересная проблема, это почти возможно сделать с помощью выражений. Поскольку метод установки принимает выражение, вы можете создать его во время выполнения.
Единственный бит, который должен произойти во время компиляции, - это приведение выражения к соответствующему лямбда-типу, основанному на типе возврата метода mocked. К сожалению, Moq не обеспечивает перегрузки Setup
, принимая голый Expression
, в противном случае можно было бы сделать то, что вы хотите, 100% во время выполнения.
public abstract class Fruit
{
}
public class Apple :Fruit
{
}
public interface IFactory {
Fruit CreateFruit(string type);
void VoidMethod(int intParameter);
}
[TestClass]
public class UnitTest1 {
[TestMethod]
public void TestMethod1() {
var factoryMock = new Mock<IFactory>();
Expression factoryCall = Expression.Lambda(
Expression.Call(Expression.Variable(typeof(IFactory), "f"), "CreateFruit", new Type[]{}, Expression.Constant("Apple")),
Expression.Parameter(typeof(IFactory), "f"));
//factoryMock.Setup(f=>f.CreateFruit("Apple")).Returns(new Apple());
factoryMock.Setup((Expression<Func<IFactory, Fruit>>)factoryCall).Returns(new Apple());
var ret = factoryMock.Object.CreateFruit("Apple");
Assert.IsInstanceOfType(ret, typeof(Apple));
}
}