Moq调用未在模拟上执行

5 unit-testing moq mocking

试图理解verifySet等的使用......但除非我做一个解决方法,否则我无法让它工作.

public interface IProduct
{
    int  Id { get; set; }
    string Name { get; set; }
}


public void Can_do_something()
{
    var newProduct = new Mock<IProduct>();
    newProduct.SetupGet(p => p.Id).Returns(1);
    newProduct.SetupGet(p => p.Name).Returns("Jo");

    //This fails!! why is it because I have not invoked it
    newProduct.VerifySet(p => p.Name, Times.AtLeastOnce());

    //if I do this it works
    newProduct.Object.Name = "Jo";
    newProduct.VerifySet(p => p.Name, Times.AtLeastOnce());
 }
Run Code Online (Sandbox Code Playgroud)

有人可以澄清我应该如何在属性上使用VerifySet和Verify和VerifyGet?我很困惑.

Gav*_*ler 10

您需要在调用verify之前执行操作.使用模拟对象的典型单元测试范例是:

// Arrange
// Act
// Assert
Run Code Online (Sandbox Code Playgroud)

所以以下是不正确的用法,因为你错过了你的Act步骤:

public void Can_do_something()
{
    // Arrange
    var newProduct = new Mock<IProduct>();
    newProduct.SetupGet(p => p.Name).Returns("Jo");

    // Act - doesn't exist!
    // Your action against p.Name (ie method call), should occur here

    // Assert
    // This fails because p.Name has not had an action performed against it
    newProduct.VerifySet(p => p.Name, Times.AtLeastOnce());
}
Run Code Online (Sandbox Code Playgroud)

这是正确的,因为法案存在:

public void Can_do_something()
{
    // Arrange
    var newProduct = new Mock<IProduct>();
    newProduct.SetupGet(p => p.Name).Returns("Jo");

    // Act
    LoadProduct(newProduct.Object);

    // Assert
    newProduct.VerifySet(p => p.Name, Times.AtLeastOnce());
}

public static void LoadProduct(IProduct product)
{
    product.Name = "Jo";
}
Run Code Online (Sandbox Code Playgroud)

模拟测试遵循与称为行为验证的非模拟测试不同的模式- 这是我做出的一个答案,它将更多地阐明概念.