【问题标题】:Mock method return based on object parameter基于对象参数的模拟方法返回
【发布时间】:2018-09-26 21:41:55
【问题描述】:

我有以下(简化的)代码:

public string methodName(ClassType object)
{
    If(object.value == 1)
        return "Yes";
    else If(object.value == 2)
        return "No";
    else
        return "whatever";
}

然后我在单元测试中调用这个方法,需要根据对象值来模拟返回类型:

_Service.Setup(x => x.methodName(new methodName { value = 1}).Returns("Yes");
_Service.Setup(x => x.methodName(new methodName { value = 2}).Returns("No");

我知道我写的是错误的 - 但我怎样才能做到这一点?

【问题讨论】:

  • 我认为这里不需要使用模拟框架。你能解释一下你需要模拟什么,也许是为什么?
  • @nvoigt,我根据自己的经验进行推测,但我假设发布者正在测试一些不同的代码,这些代码依赖于一个名为methodName() 的方法的接口。第一个示例演示了来自该接口的生产实现的示例返回数据。他在嘲笑这种依赖,而不是在测试时使用真正的依赖。

标签: c# unit-testing moq


【解决方案1】:

你在正确的轨道上。使用起订量,您需要准确指定应与每个输入匹配的设置。你这样做:

_Service.Setup(x => x.methodName(It.IsAny<ClassType>())).Returns("whatever");
_Service.Setup(x => x.methodName(It.Is<ClassType>(o => o.value == 1))).Returns("Yes");
_Service.Setup(x => x.methodName(It.Is<ClassType>(o => o.value == 2))).Returns("No");

那里的第一行设置模拟以在使用任何值调用此方法时返回“whatever”。以下两行会覆盖特定值的该行为。

我会查看 Moq 的 Quickstart 指南了解更多详情,尤其是 Matching Arguments 部分。

【讨论】:

  • 我的方法不接受 int 作为参数 - 它接受一个对象
  • 你是对的 - 我已经更新了它。您想使用 lambda 指定您的设置来评估提交的表达式。
  • 值得一提的是methodName必须是虚拟的
  • @Artem 为什么会这样 - 目前它对我来说不是虚拟的,但我所有的代码都运行良好并且工作正常?
  • @Artem,Moq 针对接口工作。在这种情况下,_Service 必须定义为某个接口,因此virtual 关键字不会出现在其中。
【解决方案2】:

我对起订量不是很熟悉,但我认为以下应该可以做到。您应该为参数的每个可能值提供一个 Returns

_Service.Setup(x => x.methodName(It.Is<ClassType>(y => y.value == 1))).Returns("Yes");
_Service.Setup(x => x.methodName(It.Is<ClassType>(y => y.value == 2))).Returns("No");

这样,每当使用object.value == 1 调用methodName 方法时,都会返回"Yes",而object.value == 2 会解析为返回"No" 的方法。

但是对我来说这没有多大意义,因为您正在以完全相同的行为嘲笑 methodName 的行为。我想这只是为了研究。

【讨论】:

  • 这是我正在做的事情的简化版本 - 以说明我所问的问题。我的实际代码与此不同
  • 另外,在模拟时——这个方法永远不会被调用,所以我需要像这样模拟它的行为——通常说当这个方法被调用时使用这个逻辑
  • @Alex 这就是嘲笑的目的。但是请注意,该方法需要在基类中是虚拟的,或者该方法是在接口上定义的
  • @Alex And is _Service 也被声明为接口类型或具体类类型?
  • 是接口类型
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
相关资源
最近更新 更多