Reputation:
Trying to understand the use of verifySet etc... but unless I do a workaround I cannot get it to work.
public interface IProduct
{
int Id { get; set; }
string Name { get; set; }
}
public void Can_do_something()
{
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Id).Returns(1);
newProduct.SetupGet(p => p.Name).Returns("Jo");
//This fails!! why is it because I have not invoked it
newProduct.VerifySet(p => p.Name, Times.AtLeastOnce());
//if I do this it works
newProduct.Object.Name = "Jo";
newProduct.VerifySet(p => p.Name, Times.AtLeastOnce());
}
Can somebody clarify how I should use VerifySet and Verify and VerifyGet on a property? I am getting confused.
Upvotes: 5
Views: 4300
Reputation:
Thanks guys Unfortunately I am new to all this and trying to learn fast.Especially the terminology "act" "arrange" etc
So eventhough i didnt understand what I was doing I did it correctly as
newProduct.Object.Name = "Jo";
was setting up an act.
Fantastic explanation guys thanks a lot
One last thing though I thought these would "set up and act" but it's not the case correct is it? do you know the diff as well between the two SetupProperty and SetupSet/Get
mock.SetupProperty(f => f.Surname, "foo");
mock.SetupSet(foo => foo.Surname = "foo");
Upvotes: 0
Reputation: 2051
You are using VerifySet() in the correct manner, you've just omitted the //Act stage from the typical
//Arrange
//Act
//Assert
test construction. As you suggested, inserting
newProduct.Object.Name = "Jo";
into your //Act stage fixes the issue.
VerifyGet() would be used in the exact same manner, e.g.
//Arrange
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Id).Returns(1);
newProduct.SetupGet(p => p.Name).Returns("Jo");
//Act
string productName = newProduct.Object.Name;
//Assert
newProduct.VerifyGet(p => p.Name, Times.AtLeastOnce());
newProduct.Verify() is used to verify whatever action you specify, e.g.
//Arrange
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Id).Returns(1);
newProduct.SetupGet(p => p.Name).Returns("Jo");
//Act
newProduct.Object.SomeMethodYouDefineOnTheProductObject();
//Assert
newProduct.Verify(p => p.SomeMethodYouDefineOnTheProductObject(), Times.AtLeastOnce());
Upvotes: 3
Reputation:
Arrange:
Instruct mock objects what is going to happen during the test. Tell it what events will fire, what methods and properties will be used, and what to do when these things happen.
Act:
Exercise the code under test.
Assert:
Ask the mock objects if what you told them to expect actually happened. Also inspect your code to see if it worked as you expected.
Your problem is that you Arranged and then Asserted without Acting inbetween. The Verify series of methods assert that what you said would happen in the Setup methods actually happened.
Upvotes: 1
Reputation: 43815
You need to perform an action before you call verify. The typical unit test paradigm with mock objects is:
// Arrange
// Act
// Assert
So the following is improper usage because you're missing your Act step:
public void Can_do_something()
{
// Arrange
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Name).Returns("Jo");
// Act - doesn't exist!
// Your action against p.Name (ie method call), should occur here
// Assert
// This fails because p.Name has not had an action performed against it
newProduct.VerifySet(p => p.Name, Times.AtLeastOnce());
}
And this is correct, since Act exists:
public void Can_do_something()
{
// Arrange
var newProduct = new Mock<IProduct>();
newProduct.SetupGet(p => p.Name).Returns("Jo");
// Act
LoadProduct(newProduct.Object);
// Assert
newProduct.VerifySet(p => p.Name, Times.AtLeastOnce());
}
public static void LoadProduct(IProduct product)
{
product.Name = "Jo";
}
Mock testing follows a different pattern than Non-Mock testing known as Behavior Verification - this is an answer I made that will clarify the concept a bit more.
Upvotes: 11