Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq Callback value does not change when callback is called

Hi I wana create a mock object where everytime the method GetPath is called i get's iterated. Here is my unit testing code:

string fileSharePath = "/fileSharePath/";
int i = 0;
m_FileShareDocumentPathProvider.Setup(p => p.GetPath(It.IsAny<IFileShareDocument>()))                                    
                               .Callback(() =>
                                   {
                                       i++;
                                       fileSharePath += i;
                                   })
                               .Returns(fileSharePath);

Here is the code In witch GetPath get's called:

foreach (var document in documents)
{
     string filePath = GetFilePath(document);
     fileSharePaths.Add(filePath);
     documentsDictionary.Add(document, filePath);
}

private string GetFilePath(IFileShareDocument document)
{
     var fileShareDocumentPathProvider = m_FileShareDocumentPathProviderFactory.GetFilePathProvider(document);
     var filePath = fileShareDocumentPathProvider.GetPath(document);
     return filePath;
}

While debugging I notice the value of fileSharePath does not change as expected , it stays the same.

What am I doing wrong?

EDIT:

  m_FileShareDocumentPathProviderFactory.Setup(f => f.GetFilePathProvider(It.IsAny<IFileShareDocument>()))
                                              .Returns(m_FileShareDocumentPathProvider.Object);
like image 979
aleczandru Avatar asked Dec 20 '22 00:12

aleczandru


1 Answers

You need to change Returns(fileSharePath) to Returns(()=>fileSharePath). When you call Returns, it passes fileSharePath by value, so that value never changes. You have to pass it in as a delegate, which causes Moq to execute that function each time it "returns" the value.

In fact you can shorten your code by eliminating the Callback and just doing .Returns(() => fileSharePath += ++i). You should rarely need to use both Callback and Returns for a single function. Callback "mock executes" a void function, and Return "mock executes" a function with a return value, and then returns that value.

like image 81
Dax Fohl Avatar answered Dec 29 '22 10:12

Dax Fohl