簡體   English   中英

Moq - 如何驗證通過setter設置的屬性值

[英]Moq - How to verify that a property value is set via the setter

考慮這個課程:

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

Checkin方法故意為空。 現在我有一些測試方法來驗證調用每個方法的狀態。

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

第二次測試通過了錯誤的原因。 那么我如何使用mocking(moq)來驗證CheckIn是否設置了IsCheckedOut屬性?

謝謝。

編輯

澄清一下:我有一個名為CheckIn()的方法,其工作是將IsCheckedOut狀態設置為false。

您將在上面的測試代碼中看到,即使我沒有將屬性值設置為false,Test也將返回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();

並在測試代碼之后:

mock.VerifySet(content => content.IsCheckedOut=It.IsAny<bool>());

我還沒有測試過,所以請告訴我它是否適合你。

編輯 實際上,由於IsCheckedOut的setter是錯誤的,所以這不起作用。

無論如何,現在我看到你從未在課程建設時設置IsCheckedOut的值。 將以下Content添加到Content類是個好主意:

public Content()
{
    IsCheckedOut=false;
}
Mock mockContect = new Mock<Cotent>(); 
mockContent.VerifySet(x => x.IsCheckedOut, Times.Once());

這會訣竅嗎? 不知道私人制定者是如何進行游戲的。 但適合我的公共制定者。

得到的信息來自: http//www.codethinked.com/post/2009/03/10/Beginning-Mocking-With-Moq-3-Part-2.aspx

你為什么不簡單地設置要檢查的內容開始? 請記住,您只測試CheckIn函數的行為。

[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真的很重要 - 在給定的場景被執行之后它應該是錯誤的。 如果你單獨進行測試,這看起來有點奇怪,但是對於任何測試都存在於集合中的東西。

如果您正在測試兩個類之間的交互,那么情況會有所不同 - 那么在屬性設置器上設置期望就好了 - 因為設置操作是您正在測試的交互。

我不熟悉Moq,因為我使用Rhino.Mocks - 但我猜測會有類似mock.VerifySet(content => content.IsCheckedOut = It.IsEqual(true));

我同意你的觀點:在這種情況下,模擬沒有價值,因為它旨在測試你的類(測試中)和世界其他地方之間的交互,而不是測試你的類的內部機制。

我認為這個測試

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

你寫的有意義而且不是誤報! 你必須確保在CheckIn之后狀態是這樣的,不管為什么會這樣; 如果將來你將在構造函數(或其他方法)中設置狀態,這個測試將保存你,你將被迫實現CheckIn方法!

在某些情況下,我想設置初始狀態,以確保我不會忘記實現CheckIn方法; 在這種情況下,我使用2種方法(第一種非常難看):

  1. 我在c.CheckIn()之前調用c.CheckOut(); 這是非常難看的,因為你測試了兩種方法而不是一種...但我承認我寫過類似的東西幾次:-)
  2. 我使私有setter受到保護,我編寫了一個繼承自被測試類的測試類; 以這種方式,我可以在調用c.CheckIn()之前將屬性設置為true,以確保該方法正在執行其工作。

這是代碼:

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

希望能有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM