如何阅读这些最小起订量设置表达式?

时间:2019-04-03 14:39:50

标签: c# unit-testing moq

备用标题:这些表达是什么意思?

编辑:This post几乎有帮助,但只是解释了两个设置功能之间的区别,而不是如何读取它们。

我正在学习如何使用最小起订量并为我的团队提供基础培训,在经历this video并查找other stackoverflow posts(以及其他)之后,我认为我已经足够了解了使用它,但仅在“这就是它的完成方式”的意义上。我没有理由或没有能力解释语法。请帮忙。

出于记录,我理解C#模板和表达式以及函数,动作和事件的使用,但是将它们结合在一起吗?元是真实的。

请考虑视频演示的单元测试之一Should_Mock_Events_Based_On_Action()unit test sourceIRepo source)中的以下代码段:

var mockRepo = new Mock<IRepo>();
mockRepo.Setup(x => x.AddRecord(null))
    .Raises(m => m.FailedDatabaseRequest += null, this, EventArgs.Empty);
  1. Setup(...)函数似乎显示为:“设置一个使用IRepo然后用AddRecord(...)调用null的函数。”但是此设置模拟了IRepo.AddRecord(...),这不是表达式。某种程度上,它可以在模拟中转换为“为IRepo设置函数{em> for AddRecord(...),这样,当使用null时,它将以某种方式起作用。”但这不是那样。 这应该怎么读?以某种方式将表达式变成某个地方的实际函数调用。

  2. Raises(...)函数确实使我感到困惑。似乎在说:“先前设置的函数引发一个事件,该事件接受一个IRepo并将null添加到其事件处理程序中。”而且...以某种方式使事件发生了吗?该+= null操作不会返回任何内容,而且我也无法弄清此处理程序正在寻找的事件如何理解它。我找到了许多文章和SO帖子,这些文章和文章都表明这就是这样做的方式,但是(我尚未找到)它们都没有解释为什么这应该怎么读?

2 个答案:

答案 0 :(得分:1)

说我有一个具有单一方法的接口ITest

public interface ITest
{
    bool IsEvent(int input);
}

然后我想嘲笑这个-记住,现在我没有没有实际的具体课程。

        var mock = new Mock<ITest>();

现在我要设置2个通话:

        mock.Setup(x => x.IsEven(1)).Returns(false);
        mock.Setup(x => x.IsEven(2)).Returns(true);

这是对模拟对象说的

  

如果调用方法IsEven的值为1,则返回false。
  如果您的方法IsEven的值为2,则返回true。

您正在设置行为以模拟对象。

因此,如果我随后在代码中执行此操作:

        var for1 = mock.Object.IsEven(1);
        var for2 = mock.Object.IsEven(2);

变量for1将为false,而for2将为true,因为我告诉模拟对象它应该这样做。 Setup的参数有效地表示“这是我要您注意的行为,然后我将告诉您该怎么做”。就我而言,我使用Returns方法来指定在特定情况下我的模拟对象实际返回的内容。

在您的特定情况下:

        mockRepo.Setup(x => x.AddRecord(null))
            .Raises(m => m.FailedDatabaseRequest += null, this, EventArgs.Empty);

这是对被嘲弄的对象

  

如果有人使用参数null调用AddRecord方法,则   引发一个类型为FailedDatabaseRequest的事件

有关Raises方法的更多信息,请在此处查看Moq quickstart documentation for events

要更深入地了解Moq引发事件,有一些有用的信息here-特别是它谈到了+= null引起您的困惑:

  

要从模拟对象引发事件,我们使用其Raise方法。这个   接受两个参数。第一个是Lambda表达式,其中包括   一个空的事件订阅者,用于引发事件。虽然不是   最优雅的语法,这是允许Moq了解如何   使用事件。第二个参数提供事件参数   将会包含在活动中。

答案 1 :(得分:0)

回答自己的问题。

我的困惑源于不了解C#的表达式(不是lambda表达式,特别是Expression<>)是如何工作的。它们是编译器理论(特别是“表达式树”)的基础,可用于将lambda解构为小块,包括参数,常量,二进制运算符等。 Moq充分利用了这一点,并使用这些片段用指定的功能+支持代码构造自己的对象以进行验证。我不知道C#可以做到这一点。

MSDN Expression

减轻我困惑的教程系列:C# Expression Trees