起订量 - 如何验证一个属性值是通过设置器所设置(Moq - How to verify that

2019-09-02 03:56发布

考虑这个类:

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

当然,我可能是错的,所以请大家帮我澄清这些概念:)

Answer 1:

下面应该工作。 配置您的模拟对象为:

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


Answer 2:

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



Answer 3:

你为什么不干脆设置要签出,开始与内容? 记住,你只是在测试签入功能的行为。

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


Answer 4:

我建议你可以在错误的方式来思考这个 - 通常你应该设置的东西了,执行操作,然后检查行为(结果)。 在这种情况下,是否真的重要,它不是由二传手设置为false - 什么应该的问题是,它是在一个给定的情景已行使后假。 如果你把在隔离测试这似乎有点奇怪,但对于什么你的测试将在台存在。

这种情况会有所不同,如果你是两个类之间测试交互 - 那么这将是罚款,以建立在属性setter的期望 - 因为设定工作是你正在测试的互动。

我不熟悉的起订量,因为我用Rhino.Mocks - 但我猜测还会有沿mock.VerifySet的线(含量=> content.IsCheckedOut = It.IsEqual(真))的东西;



Answer 5:

我同意你的看法:嘲弄在这种情况下没有价值,因为它是用来测试你的类(测试)和世界其他地区之间的相互作用,而不是测试类的内在机制。

我认为,这个测试

Content c = new Content();    
c.CheckIn();    
Assert.AreEqual(false, c.IsCheckedOut); //State verification

你写的有感觉,这是不是一个假阳性! 你必须确保状态是在checkin之后这样无论对为什么它是如此; 如果将来您将设置在构造函数中的状态(或其他方法)本次测试将节省你,你将被迫实施的CheckIn方法!

在某些情况下,类似于你我想设置的初始状态,以确保我不会忘记实现签入法; 在这种情况下我使用2种方法(第一个是非常难看):

  1. 我叫c.CheckIn前c.CheckOut()(); 这是非常丑陋的,因为你测试2种方法,而不是一个...但我承认,我写的东西相似几次:-)
  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
    }
}

希望能有所帮助。



文章来源: Moq - How to verify that a property value is set via the setter