未在模拟上执行起订量调用

发布于 2024-07-29 17:43:34 字数 674 浏览 5 评论 0原文

试图了解 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());
 }

有人可以澄清我应该如何在属性上使用VerifySet、Verify 和VerifyGet 吗? 我越来越困惑了。

Trying to understand the use of verifySet etc... but unless I do a workaround I cannot get it to work.

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());
 }

Can somebody clarify how I should use VerifySet and Verify and VerifyGet on a property?
I am getting confused.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梅倚清风 2024-08-05 17:43:34

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

// Arrange
// Act
// Assert

因此以下是不正确的用法,因为您错过了 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());
}

这是正确的,因为 Act 存在:

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";
}

模拟测试遵循与非模拟测试不同的模式,称为 行为验证 - 这是一个答案 我这样做会更加澄清这个概念。

You need to perform an action before you call verify. The typical unit test paradigm with mock objects is:

// Arrange
// Act
// Assert

So the following is improper usage because you're missing your Act step:

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());
}

And this is correct, since Act exists:

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";
}

Mock testing follows a different pattern than Non-Mock testing known as Behavior Verification - this is an answer I made that will clarify the concept a bit more.

不知在何时 2024-08-05 17:43:34

您正在以正确的方式使用VerifySet(),您只是从典型的测试构造中省略了 //Act 阶段

//Arrange

//Act

//Assert

。 正如您所建议的,插入

newProduct.Object.Name = "Jo";

//Act 阶段可以解决该问题。

verifyGet() 将以完全相同的方式使用,例如

//Arrange
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Id).Returns(1);
newProduct.SetupGet(p => p.Name).Returns("Jo");

//Act
string productName = newProduct.Object.Name;

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

newProduct.Verify() 用于验证您指定的任何操作,例如

//Arrange
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Id).Returns(1);
newProduct.SetupGet(p => p.Name).Returns("Jo");

//Act
newProduct.Object.SomeMethodYouDefineOnTheProductObject();

//Assert
newProduct.Verify(p => p.SomeMethodYouDefineOnTheProductObject(), Times.AtLeastOnce());

You are using VerifySet() in the correct manner, you've just omitted the //Act stage from the typical

//Arrange

//Act

//Assert

test construction. As you suggested, inserting

newProduct.Object.Name = "Jo";

into your //Act stage fixes the issue.

VerifyGet() would be used in the exact same manner, e.g.

//Arrange
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Id).Returns(1);
newProduct.SetupGet(p => p.Name).Returns("Jo");

//Act
string productName = newProduct.Object.Name;

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

newProduct.Verify() is used to verify whatever action you specify, e.g.

//Arrange
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Id).Returns(1);
newProduct.SetupGet(p => p.Name).Returns("Jo");

//Act
newProduct.Object.SomeMethodYouDefineOnTheProductObject();

//Assert
newProduct.Verify(p => p.SomeMethodYouDefineOnTheProductObject(), Times.AtLeastOnce());
埋葬我深情 2024-08-05 17:43:34

排列:

指示模拟对象在测试期间将发生什么。 告诉它什么事件将被触发,将使用什么方法和属性,以及当这些事情发生时要做什么。

执行:

执行被测代码。

断言

询问模拟对象您告诉他们期望的事情是否真的发生了。 还要检查您的代码,看看它是否按您的预期工作。

你的问题是你先安排然后断言,中间没有采取任何行动。 验证系列方法断言您所说的在安装方法中会发生的事情确实发生了。

Arrange:

Instruct mock objects what is going to happen during the test. Tell it what events will fire, what methods and properties will be used, and what to do when these things happen.

Act:

Exercise the code under test.

Assert:

Ask the mock objects if what you told them to expect actually happened. Also inspect your code to see if it worked as you expected.

Your problem is that you Arranged and then Asserted without Acting inbetween. The Verify series of methods assert that what you said would happen in the Setup methods actually happened.

仲春光 2024-08-05 17:43:34

多谢你们
不幸的是,我对这一切都很陌生,并试图快速学习。特别是术语“行动”“安排”等

所以即使我不明白我在做什么,我还是正确地做了

newProduct.Object.Name = “Jo”;

正在制定一项行动。

伙计们的解释太棒了
非常感谢

最后一件事
我以为这些会“设置并执行”,但事实并非如此,对吗?
你知道SetupProperty和SetupSet/Get这两个

mock.SetupProperty(f => f.Surname, "foo");

之间的区别吗? mock.SetupSet(foo => foo.Surname = "foo");

Thanks guys
Unfortunately I am new to all this and trying to learn fast.Especially the terminology "act" "arrange" etc

So eventhough i didnt understand what I was doing I did it correctly as

newProduct.Object.Name = "Jo";

was setting up an act.

Fantastic explanation guys
thanks a lot

One last thing though
I thought these would "set up and act" but it's not the case correct is it?
do you know the diff as well between the two SetupProperty and SetupSet/Get

mock.SetupProperty(f => f.Surname, "foo");

mock.SetupSet(foo => foo.Surname = "foo");

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文