When you choose to use mock objects for this purpose, you will often need to mock properties. This may involve verifying that properties are read or changed and adding expectations to either the get or set accessors. In this article we will see how this is possible using the Moq isolation framework.
![Moq Moq](/uploads/1/2/3/7/123737780/596604341.png)
Consider this class:
The Checkin method is intentionally empty. Now i have a few test methods to verify the status of calling each method.
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:
Of course I may be wrong, so please help me clarify these concepts :)
Anton P
5 Answers
The following should work. Configure your mock object as:
And after the test code:
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:
KonamimanKonamiman
Will that do the trick? Not sure how the private setter comes in to play as havent tested that. but works for my public setter.
Got this from: http://www.codethinked.com/post/2009/03/10/Beginning-Mocking-With-Moq-3-Part-2.aspx
DominicDominic
why don't you simply set up the content to be checked out to start with? Remember, you are only testing the behaviour of the CheckIn function.
Mark HeathMark Heath
Can I suggest that you might be thinking about this in the wrong way - generally you should be setting something up, performing an action and then checking the behaviour (result). In this case does it really matter that it wasn't set to false by the setter - what should matter is that it is false in after a given scenario has been exercised. If you take tests in isolation this might seem a bit odd, but for anything your tests will exist in sets.
The situation would be different if you were testing the interaction between two classes - then it would be fine to set up an expectation on the property setter - as the setting action is the interaction you're testing.
I'm not familiar with Moq as I use Rhino.Mocks - but I'm guessing there'll be something along the lines of mock.VerifySet(content => content.IsCheckedOut=It.IsEqual(true));
FinnNkFinnNk
I agree with you: mocking has no value in this scenario because it is intended to test the interactions between your class (under test) and the rest of the world, not to test the inner mechanism of your class.
I think that this test
that you write has sense and it is not a false positive! You must ensure that the state is in that way after the CheckIn regardless on why it is so; if in the future you will set the state in the constructor (or in other methods) this test will save you and you will be forced to implement the CheckIn method!
In some cases similar to your I want to set the initial state to be sure that I does not forget to implement the CheckIn method; in this case I use 2 methods (the first is very ugly):
- I call c.CheckOut() before c.CheckIn(); this is very ugly, becauseyou test 2 methods instead of one ... but I admit that I wrote something similarfew times :-)
- I make the private setter protected, and I write a test class thatinherits from the class under test; in this manner I can set theproperty to true before to call c.CheckIn() to ensure that themethod is doing his job.
Here it is the code:
Hope to help.
Daniele ArmanascoDaniele Armanasco