【问题标题】:How to mock interface that accept Type argument and return another inteface如何模拟接受类型参数的接口并返回另一个接口
【发布时间】:2017-02-22 17:32:37
【问题描述】:

我有这个界面:

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>());

但它会抛出

"不支持指定的方法。",

怎么了?

堆栈跟踪是:

在 Moq.Mock.FluentMockVisitor.VisitMember(MemberExpression 节点)
在 Moq.Mock.FluentMockVisitor.Accept() 在 Moq.Mock.FluentMockVisitor.Accept(表达式表达式,Mock mock)
在 Moq.Mock.GetInterceptor(Expression fluentExpression, Mock mock)
在 Moq.Mock.c__DisplayClass65_02.<Setup>b__0() at Moq.PexProtector.Invoke[T](Func1 函数)在 Moq.Mock.Setup[T,TResult](Mock1 mock, Expression1 表达式, 条件条件)在 Moq.Mock1.Setup[TResult](Expression1 表达式)

我也试过了:

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);

两者都抛出相同的异常。

【问题讨论】:

  • 能贴一下异常的调用栈吗?
  • @PatrickQuirk,我在问题中发布了它

标签: c# unit-testing moq


【解决方案1】:

Setup 中的表达式错误。尝试使代码更简洁,以便理解意图。

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

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

【讨论】:

    【解决方案2】:

    您应该返回模拟对象而不是模拟本身。

    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(It.IsAny())).Returns(new Mock().Object);也会抛出同样的异常
    【解决方案3】:

    你有一个错字:

    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>());
    

    【讨论】:

      【解决方案4】:

      终于成功了:

       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;
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多