This is possible with Sitecore 8.2, since the GetChildren
and Add
methods became virtual with this version. (You could create an NSubstitute Sitecore 8.1 item, but NSubstiute would not be able to interact with its methods, so there would not be any point in doing so.)
To create a Subsitute item, you need to:
Create an item ID:
var itemId = ID.NewID;
Create an item definition:
var definition = new ItemDefinition(itemId, string.Empty, ID.Null, ID.Null);
Create an item data object:
var data = new ItemData(
definition,
Language.Current,
Sitecore.Data.Version.First,
new FieldList());
Create a substitute database, which is easy in Sitecore 8.2 because the class is now abstract:
Database db = Substitute.For<Database>();
Create the substitute item, passing in the itemID, ItemData object, and substitute database as parameters:
Item item = Substitute.For<Item>(itemId, data, db);
If the code under test interacts with the Paths property, you will need to set this:
item.Paths.Returns(Substitute.For<ItemPath>(item));
Now that you have a Substitute item, you can use the Returns
and Received
methods as normal with NSubstitute:
public class ProcessorTests
{
[Fact]
public void Processor_ItemsFolderMissing_CreatesIt()
{
var sut = new DataSourceFolderCreator();
Item renderingItem = MakeSubstituteItem();
renderingItem.SetChildren(new ItemList());
renderingItem.Database.Should().NotBeNull();
var args = new GetRenderingDatasourceArgs(renderingItem, renderingItem.Database);
sut.Process(args);
renderingItem.Received()
.Add("Items", new TemplateID(TemplateIDs.Folder));
}
[Fact]
public void Processor_ItemsFolderPresent_DoesNotCreateIt()
{
var sut = new DataSourceFolderCreator();
var folderItem = MakeSubstituteItem();
var renderingItem = MakeSubstituteItem();
folderItem.Name.Returns("Items");
folderItem.TemplateID.Returns(TemplateIDs.Folder);
renderingItem.SetChildren(new ItemList { folderItem });
var args = new GetRenderingDatasourceArgs(renderingItem, renderingItem.Database);
sut.Process(args);
renderingItem.DidNotReceiveWithAnyArgs().Add("", new TemplateID());
}
private Item MakeSubstituteItem()
{
var itemId = ID.NewID;
var definition = new ItemDefinition(
itemId, string.Empty, ID.Null, ID.Null);
var data = new ItemData(
definition, Language.Current,
Sitecore.Data.Version.First, new FieldList());
var db = Substitute.For<Database>();
var item = Substitute.For<Item>(itemId, data, db);
item.Paths.Returns(Substitute.For<ItemPath>(item));
return item;
}
}
public static class ItemExtensions
{
public static void SetChildren(this Item item, ItemList items = null)
{
if (items == null)
{
items = new ItemList();
}
item.GetChildren().Returns(new ChildList(item, items));
}
}