I'm mocking the following interface:
public interface IVirtualFile
{
string Contents { get; set; }
// ...
void SaveToDisk();
// ...
}
To test this class:
public class InformationHandler
{
// ...
public void PrepareAndSaveSpecificInfo(IVirtualFile p_objSaveFile)
{
// ...
p_objSaveFile.Contents = z_strBeginning;
// ...
p_objSaveFile.Contents = String.Concat(p_objSaveFile.Contents, z_strOtherInformation);
// ...
p_objSaveFile.Contents = String.Concat(p_objSaveFile.Contents, z_strEnd);
p_objSaveFile.SaveToDisk();
}
// ...
}
With this:
[TestFixture]
public TestInformationHandler
{
private Mock<IVirtualFile> _mockVirtualFile { get; set; }
[OneTimeSetUp]
public void CreateMocks()
{
// ...
_mockVirtualFile = new Mock<IVirtualFile>();
_mockVirtualFile.Setup(vf => vf.SaveToDisk()).Callback(() => CheckSavedData());
// ...
}
private void CheckSavedData()
{
// ...
}
[Test]
public void Test_PrepareAndSaveSpecificInfo()
{
// ...
PrepareAndSaveSpecificInfo(_mockVirtualFile);
// ...
}
}
The thing is, I want CheckSavedData()
to use Assert
to test the Contents
property of my mock object.
So how can I pass said mock object to the method? Or should I make mockVirtualFile
a property of TestVirtualFile
and use it in CheckSavedData()
?
EDIT: as mentioned in the comments to vhr's answer, what I was thinking of isn't feasible, simply because a mock object's Object
property's properties don't keep the values set.
To make it even clearer, step-by-step debugging indicates that right after
_mockVirtualFile.Contents = "abcdef";
the property _mockVirtualFile.Contents
still returns null
.
By using 'Setup', you are mocking the 'SaveToDisk' method behavior which means that you are telling Moq to execute the callback each time you call your object's method from test:
private Mock<IVirtualFile> mockVirtualFile;
[OneTimeSetUp]
public void CreateMocks()
{
// ...
mockVirtualFile = new Mock<IVirtualFile>();
mockVirtualFile.Setup(vf => vf.SaveToDisk()).Callback(() => CheckSavedData());
// ...
}
[Test]
public void TestMethod()
{
var mockedFile = mockVirtualFile.Object;
mockedFile.SaveToDisk(); //this will call CheckSavedData() method
...
}
so if you want to do any assertion you can just do e.g:
mockedFile.SaveToDisk();
Assert.True(mockedFile.Contents == null)
As the Moq framework is used to 'mock' some behavior you should actually modify your 'Contents' property inside your mocked method otherwise there is no point in asserting the 'Contents' as it will be always null...