如何模拟接受 Type 参数和 return 另一个接口的接口

How to mock interface that accept Type argument and return another inteface

我有这个界面:

public interface IViewModelCache
{
    IViewModel GetViewModel(Type viewModelType);
}

我用这段代码来模拟它:

var cacheMock = Mock.Of<IViewModelCache>();

Mock.Get(cacheMock)
    .Setup(cache => cacheMock.GetViewModel(typeof(IViewModel)))
    .Returns(Mock.Of<IViewModel>());

但是它抛出

"Specified method is not supported.",

怎么了?

堆栈跟踪是:

at Moq.Mock.FluentMockVisitor.VisitMember(MemberExpression node)
at Moq.Mock.FluentMockVisitor.Accept() at Moq.Mock.FluentMockVisitor.Accept(Expression expression, Mock mock)
at Moq.Mock.GetInterceptor(Expression fluentExpression, Mock mock)
at Moq.Mock.<>c__DisplayClass65_02.<Setup>b__0() at Moq.PexProtector.Invoke[T](Func1 function) at Moq.Mock.Setup[T,TResult](Mock1 mock, Expression1 expression, Condition condition) at Moq.Mock1.Setup[TResult](Expression1 expression)

我也试过了:

Mock.Get(cacheMock)
   .Setup(cache => cacheMock.GetViewModel(It.IsAny<Type>()))
   .Returns(Mock.Of<IViewModel>());

还有那个:

Mock.Get(cacheMock)
   .Setup(cache => cacheMock.GetViewModel(It.IsAny<Type>()))
   .Returns(new Mock<IViewModel>().Object);

两者抛出相同的异常。

您应该 return 模拟的对象而不是模拟本身。

Returns(Mock.Of<IViewModel>())

应该是

Returns(new Mock<IViewModel>().Object)

更新

试试这个

var cacheMock = new Mock<IViewModelCache>();
cacheMock.Setup(c => c.GetViewModel(typeof(IViewModel)))
         .Returns(new Mock<IViewModel>().Object);

你打错了:

Mock.Get(cacheMock)
    .Setup(cache => cacheMock.GetViewModel(typeof(IViewModel)))
    .Returns(Mock.Of<IViewModel>());

应该是(注意 Setup 调用):

Mock.Get(cacheMock)
    .Setup(cache => cache.GetViewModel(typeof(IViewModel)))
    .Returns(Mock.Of<IViewModel>());

设置中的表达式有误。尝试使代码更简洁,以便理解其意图。

var cache = Mock.Of<IViewModelCache>();
var viewModel = Mock.Of<IViewModel>();
var viewModelType = typeof(IViewModel);

Mock.Get(cache)
   .Setup(mock => mock.GetViewModel(viewModelType))
   .Returns(viewModel);

终于成功了:

 public static IViewModelCache MockViewModelCache()
 {
     var cache = Mock.Of<IViewModelCache>();
     var viewModel = Mock.Of<RoutableViewModelBase<IReportData>>();

     Mock.Get(cache)
        .Setup(mock => mock.GetViewModel(It.IsAny<Type>)))
        .Returns(viewModel);

     return cache;
 }