I need to mock a sharepoint document library returning a list of 6 files. This is the logic I am using to create a mock system.
public class SharePointDocLibraryUtilsTestFactory
{
private Mock<IPnPCoreSDKClient> _mockPnPCoreSDKClient;
private Mock<IPnPContext> _mockPnpContext;
private ITestOutputHelper _output;
public SharePointDocLibraryUtilsTestFactory(ITestOutputHelper output)
{
_mockPnPCoreSDKClient = new Mock<IPnPCoreSDKClient>();
_mockPnpContext = new Mock<IPnPContext>();
_mockPnPCoreSDKClient.Setup(client => client.GetPnPContextAsync(It.IsAny<string>())).ReturnsAsync(_mockPnpContext.Object);
_output = output;
}
public IList SetupMockSharePointLibrary()
{
var mockList = new Mock<IList>();
var mockRootFolder = new Mock<IFolder>();
var mockWeb = new Mock<IWeb>();
var subfolders = new List<IFolder>();
for (int i = 0; i < 3; i++)
{
var mockFolder = new Mock<IFolder>();
var mockFileCollection = new Mock<IFileCollection>();
var mockFiles = new List<IFile>();
for (int j = 0; j < 2; j++)
{
var mockFile = new Mock<IFile>();
mockFile.Setup(f => f.Name).Returns($"File_{i}_{j}.txt");
mockFile.Setup(f => f.ServerRelativeUrl).Returns($"/sites/me/Documents/folder_{i}/File_{i}_{j}.txt");
mockFiles.Add(mockFile.Object);
}
mockFileCollection.Setup(m => m.GetEnumerator()).Returns(() => mockFiles.GetEnumerator());
mockFolder.Setup(f => f.Files).Returns(mockFileCollection.Object);
subfolders.Add(mockFolder.Object);
}
// Setup folder collection to return our mock folders
var mockFolderCollection = new Mock<IFolderCollection>();
mockFolderCollection.Setup(m => m.GetEnumerator()).Returns(() => subfolders.GetEnumerator());
mockRootFolder.Setup(f => f.Folders).Returns(mockFolderCollection.Object);
// Setup the mock list to return the root folder and the correct item count
mockList.Setup(l => l.RootFolder).Returns(mockRootFolder.Object);
// Setup the mock web to return the mock list
mockWeb.Setup(web => web.Lists.GetByTitleAsync(It.IsAny<string>(), It.IsAny<Expression<Func<IList, object>>>()))
.ReturnsAsync(mockList.Object);
//mockList.Setup(l => l.RootFolder).Returns(mockRootFolder.Object);
//mockWeb.Setup(web => web.Lists.GetByTitleAsync(It.IsAny<string>(), It.IsAny<Expression<Func<IList, object>>>()))
// .ReturnsAsync(mockList.Object);
_output.WriteLine($"Total file list count {mockList.Object.ItemCount}");
return mockList.Object;
}
When i debug this code, I can see that the mockFolderCollection is empty. This is the output from my immediate window:
mockFolderCollection
{Mock<IFolderCollection:1>}
Behavior: Default
CallBase: false
DefaultValue: Empty
DefaultValueProvider: {Moq.EmptyDefaultValueProvider}
Invocations: {Moq.InvocationCollection}
Name: "Mock<IFolderCollection:1>"
Object (Moq.Mock): {Mock<IFolderCollection:1>.Object}
Object: {Mock<IFolderCollection:1>.Object}
Setups: {Moq.SetupCollection}
Switches: Default
Because this is empty, when it calls the SUT, i get a null error by the time it hits this specific function:
private async Task ProcessFolderAsync(IFolder folder, SharePointDocLibraryInventory result, bool recursive, string checksumType)
{
// Process files in the current folder
foreach (var file in folder.Files)
{
string checksum = await GenerateChecksumAsync(file, checksumType);
result.Files.Add(new SynchronizedSharePointDocument
{
Name = file.Name,
FullPath = file.ServerRelativeUrl,
RelativePath = file.ServerRelativeUrl.Replace(folder.ServerRelativeUrl, "").TrimStart('/'),
Checksum = checksum
});
result.TotalFiles++;
}
// Optionally process subfolders recursively
if (recursive)
{
await folder.LoadAsync(f => f.Folders);
foreach (var subfolder in folder.Folders)
{
result.TotalSubdirectories++;
await ProcessFolderAsync(subfolder, result, recursive, checksumType);
}
}
}
The folder parameter comes in as null.