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

Anton P picture Anton P · Oct 29, 2009 · Viewed 38.5k times · Source

Consider this class:

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

The Checkin method is intentionally empty. Now i have a few test methods to verify the status of calling each method.

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

The 2nd test passes for the wrong reasons. So how can i use mocking (moq) to verify that CheckIn is setting the IsCheckedOut property?

Thanks.

EDIT

To clarify: I have a method called CheckIn() whose job it is to set the IsCheckedOut status to false.

You will see in my test code above that the Test will return false even if i do not set the property value to false; This is expected, nothing wrong here.

I think my question specifically is How can i verify that the CheckIn() method has set the IsCheckedOut property to false? This is what I would call behavioral verification.

I believe some of the comments suggested doing something which amounts to state verification? If so I don't believe there is any value in mocking this part at all when we can simply use:

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

Of course I may be wrong, so please help me clarify these concepts :)

Answer

Konamiman picture Konamiman · Oct 29, 2009

The following should work. Configure your mock object as:

var mock=new Mock<IContent>();
mock.SetupSet(content => content.IsCheckedOut=It.IsAny<bool>()).Verifiable();

And after the test code:

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

I haven't tested it anyway, so please tell me if it works for you.

EDIT. Indeed, this will not work since the setter for IsCheckedOut is false.

Anyway, now I see that you never set the value of IsCheckedOut at class construction time. It would be a good idea to add the following to the Content class:

public Content()
{
    IsCheckedOut=false;
}