C# Moq-如何验证是否通过setter设置了属性值
以这一类为例:C# Moq-如何验证是否通过setter设置了属性值,c#,.net,mocking,tdd,moq,C#,.net,Mocking,Tdd,Moq,以这一类为例: public class Content { public virtual bool IsCheckedOut {get; private set;} public virtual void CheckOut() { IsCheckedOut = true; } public virtual void CheckIn() { //Do Nothing for now as demonstrating fal
public class Content
{
public virtual bool IsCheckedOut {get; private set;}
public virtual void CheckOut()
{
IsCheckedOut = true;
}
public virtual void CheckIn()
{
//Do Nothing for now as demonstrating false positive test.
}
}
签入方法故意为空。现在我有一些测试方法来验证调用每个方法的状态
[TestMethod]
public void CheckOutSetsCheckedOutStatusToTrue()
{
Content c = new Content();
c.CheckOut();
Assert.AreEqual(true, c.IsCheckedOut); //Test works as expected
}
[TestMethod]
public void CheckInSetsCheckedOutStatusToFalse()
{
Content c = new Content();
c.CheckIn();
Assert.AreEqual(false, c.IsCheckedOut); //Test does not work as expected
}
第二次测试因错误原因通过。那么,如何使用mock(moq)来验证签入是否正在设置IsCheckedOut属性呢
谢谢
编辑
澄清一下:我有一个名为CheckIn()的方法,其任务是将IsCheckedOut状态设置为false
您将在上面的测试代码中看到,即使我没有将属性值设置为false,测试也将返回false;这是意料之中的,这里没有什么问题
我想我的问题是如何验证CheckIn()方法是否已将IsCheckedOut属性设置为false?这就是我所说的行为验证
我相信一些评论建议做一些相当于国家核查的事情?如果是这样的话,当我们可以简单地使用以下内容时,我认为嘲笑这一部分根本没有任何价值:
Content c = new Content();
c.CheckIn();
Assert.AreEqual(false, c.IsCheckedOut); //State verification
当然,我可能是错的,所以请帮我澄清这些概念:)以下应该可以。将模拟对象配置为:
var mock=new Mock<IContent>();
mock.SetupSet(content => content.IsCheckedOut=It.IsAny<bool>()).Verifiable();
我是否可以建议您可能以错误的方式思考这个问题-通常您应该设置一些东西,执行一个操作,然后检查行为(结果)。在这种情况下,setter没有将其设置为false真的很重要吗?重要的是,在给定场景被执行之后,它在中是false。如果您单独进行测试,这可能看起来有点奇怪,但对于任何事情,您的测试都将以集合的形式存在 如果您正在测试两个类之间的交互,情况会有所不同——那么在属性setter上设置一个期望值就可以了——因为设置操作就是您正在测试的交互
我不熟悉Moq,因为我使用Rhino.Mocks——但我猜mock.VerifySet(content=>content.IsCheckedOut=It.IsEqual(true)) 为什么不先设置要签出的内容?请记住,您只是在测试签入函数的行为
[TestMethod]
public void CheckInSetsCheckedOutStatusToFalse()
{
// arrange - create a checked out item
Content c = new Content();
c.CheckOut();
// act - check it in
c.CheckIn();
// assert - IsCheckedOut should be set back to false
Assert.AreEqual(false, c.IsCheckedOut);
}
Mock mockContect=new Mock();
mockContent.VerifySet(x=>x.IsCheckedOut,Times.Once());
这样行吗?我不知道这位二传手是如何上场的,因为我还没有测试过。但对我的公众设定者有效
我同意你的观点:模拟在这个场景中没有任何价值,因为它是为了测试你的类(被测试)和世界其他地方之间的交互,而不是测试你的类的内部机制 我认为这个测试
Content c = new Content();
c.CheckIn();
Assert.AreEqual(false, c.IsCheckedOut); //State verification
你写的东西很有道理,不是假阳性!您必须确保签入后的状态是这样的,无论其原因为何;如果将来您将在构造函数(或其他方法)中设置状态,此测试将保存您,并且您将被迫实现签入方法
在某些情况下,与您的类似,我希望设置初始状态,以确保不会忘记实现CheckIn方法;在本例中,我使用了两种方法(第一种非常难看):
public class Content2
{
public virtual bool IsCheckedOut { get; protected set; }
public virtual void CheckOut()
{
IsCheckedOut = true;
}
public virtual void CheckIn()
{
//Do Nothing for now as demonstrating false positive test.
}
}
[TestClass]
public class Content2Test : Content2
{
[TestMethod]
public void CheckOutSetsCheckedOutStatusToTrue()
{
this.CheckOut();
Assert.AreEqual(true, this.IsCheckedOut); //Test works as expected
}
[TestMethod]
public void CheckInSetsCheckedOutStatusToFalse()
{
this.IsCheckedOut = true;
this.CheckIn();
Assert.AreEqual(false, this.IsCheckedOut); //Test does not work as expected
}
}
希望对您有所帮助。请澄清。我不想在IsCheckedOut属性上测试setter,而是想测试CheckIn()方法是否设置了IsCheckedOut=false;另外,IsCheckedOut属性是私有的,所以我认为设置不会起作用。我想做的事有可能吗?还有什么想法吗?IsCheckedOut在你的接口中,所以它不能是私有的?Finnk:只有getter在接口中,setter是私有的。我正在使用实现类-Content.oops进行测试,是的,很抱歉,我在阅读问题时遗漏了私有修饰符。这实际上取决于IsChecked out属性的用途-如果对象的行为是签入后签出为false,那么上面的内容就可以了。如果属性是一个进入类的窗口,用于检查更大的行为,那么这就是我所说的状态验证。所以…实际上取决于意图。这似乎解决了问题:没有直接回答问题,但我需要检查属性是否显式设置为true:
mock.SetupProperty(foo=>foo.SomeProperty);/*运行测试操作*/;mock.VerifySet(foo=>foo.SomeProperty=It.IsAny(),“应该设置SomeProperty”);True(mock.Object.SomeProperty,“SomeProperty应该设置为True”)代码>我同意在这种情况下不需要使用模拟(ing框架)。这个建议的方法更好,因为它测试的是公共接口,而不是内部细节(即属性如何设置)。这应该是可以接受的答案。这里没有什么可嘲笑的<代码>内容
是正在测试的单元。我必须将我的属性标记为虚拟,否则Moq拒绝验证它们。
Mock mockContect = new Mock<Cotent>();
mockContent.VerifySet(x => x.IsCheckedOut, Times.Once());
Content c = new Content();
c.CheckIn();
Assert.AreEqual(false, c.IsCheckedOut); //State verification
public class Content2
{
public virtual bool IsCheckedOut { get; protected set; }
public virtual void CheckOut()
{
IsCheckedOut = true;
}
public virtual void CheckIn()
{
//Do Nothing for now as demonstrating false positive test.
}
}
[TestClass]
public class Content2Test : Content2
{
[TestMethod]
public void CheckOutSetsCheckedOutStatusToTrue()
{
this.CheckOut();
Assert.AreEqual(true, this.IsCheckedOut); //Test works as expected
}
[TestMethod]
public void CheckInSetsCheckedOutStatusToFalse()
{
this.IsCheckedOut = true;
this.CheckIn();
Assert.AreEqual(false, this.IsCheckedOut); //Test does not work as expected
}
}