Mocking Sitecore services
Using NSubstitute, we can easily create mocks for the necessary service interfaces to use in the mock ServiceCollection. IRendering and IPageContext :
private static IRendering MockRendering(Db fakeDb) { var renderingMock = Substitute.For<IRendering>(); renderingMock.DataSourceItem.Returns(fakeDb.GetItem(ItemId)); return renderingMock; } private static IPageContext MockPageContext(Db fakeDb) { var contextMock = Substitute.For<IPageContext>(); contextMock.Current.Returns(fakeDb.GetItem(ItemId)); return contextMock; } private static IControlEditabilityService MockIControlEditabilityService() { var mock = Substitute.For<IControlEditabilityService>(); var editabilityMock = Substitute.For<IControlEditability>(); editabilityMock.Editable.Returns(false); mock.GetControlEditability(Arg.Any<IRendering>()).Returns(editabilityMock); return mock; }
Note that both IRendering and IPageContext get the item you're going to mock per unittest and that's already in the FakeDb. The items they return should be the same and be easily specifyable in each TestMethod, so I've added this line to my test baseclass:
protected static ID ItemId = ID.NewID;
This ID is then used to create, add and retrieve a DbItem to and from the FakeDb. This same item also needs to be set as the current item in the Context:
Context.Items["sc_CurrentItem"] = fakeDb.GetItem(ItemId);
Usage in testcases
Because all the mocking work needed to run the tests is done in a baseclass, all you need in unit-specific test class is a way to get your repository (I've made the baseclass using generics so it automatically registers IMyService with MyService as implementation class in the ServiceCollection):
private MyRepository Repository { get { return ServiceLocator.Current.ServiceProvider.GetService(typeof(IMyRepository)) as MyRepository; } }
and, of course, tying it all up in a testcase, where SetupServices is described in the previous post:
[TestMethod] public void FillExtraProperties_FillsTitle() { using (var fakeDb = new Db()) { // Arrange var item = new DbItem("MyItemName", ItemId, SitecoreItemConstants.TemplateId) { { SitecoreItemConstants.TitleFieldSelector, "testtitel" } }; fakeDb.Add(item); SetupServices(fakeDb).FinalizeSetup(); // Act var result = Repository.GetModel() as MykModel; // Assert Assert.IsNotNull(result); Assert.AreEqual("testtitel", result.MyTitle); } }
And there you have it! If there's anything still unclear with the process don't hesitate to drop a comment. Happy testing!
No comments:
Post a Comment