考虑这个类:
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
}
第2测试通过错误的原因。 那么,如何可以使用嘲讽(MOQ)来验证检入被设置IsCheckedOut财产?
谢谢。
编辑
为了澄清:我有()的工作就是到IsCheckedOut状态设置为false称为签入的方法。
你会在我的测试代码上面的测试将返回false,即使我没有设置该属性值设置为false看; 这是预期,没有什么错在这里。
我想我的问题是具体如何我确认签入()方法的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();
而测试代码后:
mock.VerifySet(content => content.IsCheckedOut=It.IsAny<bool>());
我没有测试它,无论如何,所以请告诉我,如果你的作品。
编辑 。 事实上,这是不行的,因为对于二传手IsCheckedOut
是假的。
不管怎样,现在我知道你永远不会设置的值IsCheckedOut
在一流的施工时间。 这将是一个好主意,添加以下的Content
类:
public Content()
{
IsCheckedOut=false;
}
Mock mockContect = new Mock<Cotent>();
mockContent.VerifySet(x => x.IsCheckedOut, Times.Once());
请问是这样的伎俩? 不知道私人二传手怎么进来的还没有测试该打。 但适合我的公共setter方法。
:从有这个http://www.codethinked.com/post/2009/03/10/Beginning-Mocking-With-Moq-3-Part-2.aspx
你为什么不干脆设置要签出,开始与内容? 记住,你只是在测试签入功能的行为。
[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);
}
我建议你可以在错误的方式来思考这个 - 通常你应该设置的东西了,执行操作,然后检查行为(结果)。 在这种情况下,是否真的重要,它不是由二传手设置为false - 什么应该的问题是,它是在一个给定的情景已行使后假。 如果你把在隔离测试这似乎有点奇怪,但对于什么你的测试将在台存在。
这种情况会有所不同,如果你是两个类之间测试交互 - 那么这将是罚款,以建立在属性setter的期望 - 因为设定工作是你正在测试的互动。
我不熟悉的起订量,因为我用Rhino.Mocks - 但我猜测还会有沿mock.VerifySet的线(含量=> content.IsCheckedOut = It.IsEqual(真))的东西;
我同意你的看法:嘲弄在这种情况下没有价值,因为它是用来测试你的类(测试)和世界其他地区之间的相互作用,而不是测试类的内在机制。
我认为,这个测试
Content c = new Content();
c.CheckIn();
Assert.AreEqual(false, c.IsCheckedOut); //State verification
你写的有感觉,这是不是一个假阳性! 你必须确保状态是在checkin之后这样无论对为什么它是如此; 如果将来您将设置在构造函数中的状态(或其他方法)本次测试将节省你,你将被迫实施的CheckIn方法!
在某些情况下,类似于你我想设置的初始状态,以确保我不会忘记实现签入法; 在这种情况下我使用2种方法(第一个是非常难看):
- 我叫c.CheckIn前c.CheckOut()(); 这是非常丑陋的,因为你测试2种方法,而不是一个...但我承认,我写的东西相似几次:-)
- 我做私人二传手保护,我写一个测试类,从被测类继承; 以这种方式,我可以将属性设置为true之前调用c.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
}
}
希望能有所帮助。