需要帮助了解起订量更好(Need help to understand Moq better)

2019-06-24 17:55发布

我一直在寻找的起订量文档和评论太短,我了解每个事情可以做。

我不明白的第一件事就是It.IsAny<string>(). //example using string It.IsAny<string>(). //example using string

有没有使用这种过度只是把一些价值的优势? 我知道人们会说使用这个,如果你不关心的值,但是如果你不关心的值不能你只是做“一”的东西? 这似乎只是更多的输入。

其次,当将是一个例子是,当你不会在乎的价值? 我认为起订量需要的东西相匹配的值。

我不明白什么It.Is<>是在所有或如何使用它。 我不明白的例子,它试图展现。

接下来,我不明白何时使用Times (及其AtMost方法和类似)。 为什么要限制时间的东西是建立在多少? 我有一些AppConfig价值,我需要使用两次。 我为什么要限制它,比方说,一次? 这只是使测试失败。 这是阻止其他人加入另一个给你的代码还是什么?

我不明白如何使用mock.SetupAllProperties(); 这是什么设置的属性用?

我不也明白为什么有这么多不同的方式来建立财产和他们的区别是什么。 该文件有:

SetupGet(of property)
SetupGet<TProperty>

我注意到,在起订量显示了很多的东西()<> -什么是它们之间的区别,他们是什么样子的使用?

我也不知道为什么他们SetupGet 。 你会不会使用SetupSet设置属性? SetupSet有五种不同的方式在文档中使用它。 加上另外一个叫SetupProperty 。 所以,我不明白为什么有这么多。

在一个侧面说明,如果在lambda表达式中使用的变量是独立于其他的lambda表达式我想知道。 例如:

mock.setup(m => m.Test);
stop.setup(m => m.Test);

这会是好的,会有变量之间的一些冲突m

最后,我在看这个视频 ,我想知道如果它显示的Visual Studio。 他的智能感知看起来不同。 一个灯泡弹出他(我很高兴我的不对,因为它带回的netbeans的痛苦的回忆),并有行从一个左括号要结束花等。

谢谢 :)

Answer 1:

It.IsAny / It.Is

当你在代码中测试通过了新的引用类型,这些可能是有用的。 例如,如果你有沿的线的方法: -

public void CreatePerson(string name, int age) {
    Person person = new Person(name, age);
    _personRepository.Add(person);
}

你可能要检查的添加方法被调用的库

[Test]
public void Create_Person_Calls_Add_On_Repository () {
    Mock<IPersonRepository> mockRepository = new Mock<IPersonRepository>();
    PersonManager manager = new PersonManager(mockRepository.Object);
    manager.CreatePerson("Bob", 12);
    mockRepository.Verify(p => p.Add(It.IsAny<Person>()));
}

如果你想使这个测试更明确的,你可以通过提供一个谓语人对象必须匹配使用It.Is

[Test]
public void Create_Person_Calls_Add_On_Repository () {
    Mock<IPersonRepository> mockRepository = new Mock<IPersonRepository>();
    PersonManager manager = new PersonManager(mockRepository.Object);
    manager.CreatePerson("Bob", 12);
    mockRepository.Verify(pr => pr.Add(It.Is<Person>(p => p.Age == 12)));
}

通过这种方式,测试将通过一个异常,如果这是用来调用add方法的人对象没有年龄属性设置为12。

如果你有沿的线的方法: -

public void PayPensionContribution(Person person) {
    if (person.Age > 65 || person.Age < 18) return;
    //Do some complex logic
    _pensionService.Pay(500M);
}

其中之一,你可能要测试的事情是,当65岁以上的人被传递到方法支付方法不会被调用

[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {
    Mock<IPensionService> mockPensionService = new Mock<IPensionService>();
    Person p = new Person("test", 66);
    PensionCalculator calc = new PensionCalculator(mockPensionService.Object);
    calc.PayPensionContribution(p);
    mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}

同样有可能设想在那里你遍历集合,并要求每个项目的方法集合中的情况下,你想确保它已经称为了一定的时间,其他时候,你根本不在乎。

SetupGet / SetupSet

你需要知道这些家伙是什么,他们是如何体现你的代码与模拟互动,而不是你如何建立模拟

public static void SetAuditProperties(IAuditable auditable) {
    auditable.ModifiedBy = Thread.CurrentPrincipal.Identity.Name;
}

在这种情况下,代码被设置IAuditable了实例的ModifiedBy财产,而它得到的IPrincipal的当前实例的名称属性

[Test]
public void Accesses_Name_Of_Current_Principal_When_Setting_ModifiedBy() {
    Mock<IPrincipal> mockPrincipal = new Mock<IPrincipal>();
    Mock<IAuditable> mockAuditable = new Mock<IAuditable>();

    mockPrincipal.SetupGet(p => p.Identity.Name).Returns("test");

    Thread.CurrentPrincipal = mockPrincipal.Object;
    AuditManager.SetAuditProperties(mockAuditable.Object);

    mockPrincipal.VerifyGet(p => p.Identity.Name);
    mockAuditable.VerifySet(a => a.ModifiedBy = "test");
}

在这种情况下,我们正在设置的name属性上的IPrincipal的模仿,因此返回“测试”时,吸气叫上标识的名称属性我们不设置该属性本身。

设置属性/ SetupAllProperties

综观上述试验如果它被改为

[Test]
public void Accesses_Name_Of_Current_Principal_When_Setting_ModifiedBy() {
    Mock<IPrincipal> mockPrincipal = new Mock<IPrincipal>();
    Mock<IAuditable> mockAuditable = new Mock<IAuditable>();
    mockPrincipal.SetupGet(p => p.Identity.Name).Returns("test");

    var auditable = mockAuditable.Object;

    Thread.CurrentPrincipal = mockPrincipal.Object;
    AuditManager.SetAuditProperties(auditable);

    Assert.AreEqual("test", auditable.ModifiedBy);
}

该测试将失败。 这是因为,起订量创建的代理实际上并没有做任何事情,在属性的设置方法,除非你告诉它。 在影响模拟对象看上去有点像这样

public class AuditableMock : IAuditable {
     public string ModifiedBy { get { return null; } set { } }

} 

为了让测试通过,你必须告诉起订量来设置属性,使其具有标准特性的行为。 您可以通过调用SetupProperty做到这一点,模拟看起来更像

public class AuditableMock : IAuditable {
     public string ModifiedBy { get; set; }
} 

以上测试将通过为值“测试”会现在就对存储的模拟。 当嘲讽复杂的对象,你可能要为所有属性做到这一点,因此SetupAllProperties快捷方式

最后,在IDE中的灯泡是ReSharper的插件。



Answer 2:

如果你不关心的属性的精确值,这是迄今为止最好使用.IsAny因为你正在明确的事实,确切值并不重要。 如果你硬编码为“ABC”,那么它是不明确的,如果你的代码是测试取决于与“一”开始或以“C”结尾或为3个字符长,等等等等。



文章来源: Need help to understand Moq better