Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Moq-如何验证是否通过setter设置了属性值_C#_.net_Mocking_Tdd_Moq - Fatal编程技术网

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方法;在本例中,我使用了两种方法(第一种非常难看):

  • 我在c.CheckIn()之前调用c.CheckOut();这很难看,因为 你测试两种方法而不是一种。。。但我承认我写过类似的东西 几次:-)
  • 我使私有setter受到保护,并编写了一个测试类 从被测试的类继承;通过这种方式,我可以设置 在调用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
        }
    }
    

    希望对您有所帮助。

    请澄清。我不想在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
        }
    }