【问题标题】:Mock a Property Getter Throw an Exception Using Reflection使用反射模拟属性获取器抛出异常
【发布时间】:2013-12-11 17:20:38
【问题描述】:

我想模拟一个我发现的属性,当有人试图从中获取时,我使用反射抛出异常。问题是我不知道ID 的类型。以下是我尝试过的示例:

internal static T CreateObjectWithExceptioningIDProperty<T>() where T : class
{
  Type type = typeof(T);
  var moq = new Mock<T>();
  var lambdaParameter = Expression.Parameter(type);
  PropertyInfo idProperty = type.GetProperties().First(pi => pi.Name.Equals("ID"));
  var lambdaBody = Expression.Property(lambdaParameter, idProperty);
  dynamic func = Expression.Lambda(lambdaBody, lambdaParameter);
  moq.Setup(func).Throws(new Exception()); // get RuntimeBinderException
  return moq.Object;
}

目前,我收到了RuntimeBinderException: 'object' does not contain a definition for 'Throws'。我做错了什么?

这类似于Moq and reflection, passing dynamically generated expression tree / lambda to moqCreate an Expression<Func<,>> using reflection

【问题讨论】:

  • 你的RuntimeBinderException 是因为你不能在dynamic 类型上使用扩展方法(因为funcdynamicmoq.Setup(func) 也是)。也许将其转换为适当的类型或不使用扩展方法语法?
  • 这是用于单元测试的吗?如果是这样,它的代码有异味。
  • 是的,它是用于单元测试的,但这是一个很长的故事(遗留代码)。

标签: c# reflection moq


【解决方案1】:

如果您将Setup 的结果转换为IThrows,它会起作用。我不确定为什么它会失败。可能是因为moq.Setup(func) 的运行时类型通常不可见(它是internalMoq)。

((IThrows)moq.Setup(func)).Throws(new Exception());

【讨论】:

  • 我敢打赌这是因为Setup() 是一种扩展方法(就像您在上面评论的那样)。
  • @MageWind 实际上,我认为SetupThrows 都不是扩展方法。当我写评论时,我猜想Throws 是,但我错了。
【解决方案2】:

也许

moq.Setup( x => x.Id).Throws(new Exception());

?

【讨论】:

  • 您可能会考虑在您的答案中添加更多内容,特别是因为您似乎不确定它是否正确。
  • 你好像不太确定
  • 是的,可以,但我忘了提到在编译时我不会知道属性的名称。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 2019-08-30
  • 2017-05-14
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
相关资源
最近更新 更多