尝试理解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? 我很困惑。
答案 0 :(得分:10)
您需要在致电验证前执行操作。使用模拟对象的典型单元测试范例是:
// 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());
}
这是正确的,因为法案存在:
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";
}
模拟测试遵循的模式与非模拟测试的模式不同,称为行为验证 - 这是我做的answer,它将更多地阐明这个概念。
答案 1 :(得分:3)
你正在以正确的方式使用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());
答案 2 :(得分:1)
<强>安排:强>
指示模拟对象在测试期间会发生什么。告诉它将触发哪些事件,将使用哪些方法和属性,以及在这些事情发生时该怎么做。
<强>法强>
练习测试中的代码。
<强>断言:强>
询问模拟对象是否告诉他们实际发生的事情。还要检查您的代码,看它是否按预期工作。
你的问题是你安排然后断言而不介入。 Verify系列方法声明您所说的将在Setup方法中实际发生的事情。
答案 3 :(得分:0)
谢谢你们 不幸的是,我是所有这一切的新手,并试图快速学习。特别是术语“行为”“安排”等
所以虽然我不明白我在做什么,但我做得正确
newProduct.Object.Name =“Jo”;
正在制定一项法案。
神奇的解释家伙 非常感谢
最后一件事 我认为这些会“设置并采取行动”,但事实并非如此正确吗? 你知道两个SetupProperty和SetupSet / Get
之间的差异mock.SetupProperty(f =&gt; f.Surname,“foo”);
mock.SetupSet(foo =&gt; foo.Surname =“foo”);