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