I'm a sitecore developer and I want to create a sample sitecore helix unit testing project for testing out the logic you see in our "ArticleController" controller's Index() action method:
public class ArticleController : GlassController
{
public override ActionResult Index()
{
// If a redirect has been configured for this Article, then redirect to new location.
if (Sitecore.Context.Item.Fields[SitecoreFieldIds.WTW_REDIRECT_TO] != null && !string.IsNullOrEmpty(Sitecore.Context.Item.Fields[SitecoreFieldIds.WTW_REDIRECT_TO].Value))
{
var link = (LinkField)Sitecore.Context.Item.Fields[SitecoreFieldIds.WTW_REDIRECT_TO];
if (link != null)
{
if (link.IsInternal)
{
return Redirect(Sitecore.Links.LinkManager.GetItemUrl(link.TargetItem));
}
else
{
return Redirect(link.Url);
}
}
}
var model = new ArticleBusiness().FetchPopulatedModel;
return View("~/Views/Article/Article.cshtml", model);
}
//below is alternative code I wrote for mocking and unit testing the logic in above Index() function
private readonly IArticleBusiness _businessLogic;
public ArticleController(IArticleBusiness businessLogic)
{
_businessLogic = businessLogic;
}
public ActionResult Index(int try_businessLogic)
{
// How do we replicate the logic in the big if-statement in above "override ActionResult Index()" method?
var model = _businessLogic.FetchPopulatedModel;
return View("~/Views/EmailCampaign/EmailArticle.cshtml", model);
}
}
This is what I have in my unit testing class:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_ArticleController_With_SitecoreItem()
{
//Arrange
var businessLogicFake = new Mock<IArticleBusiness>();
var model = new ArticleViewModel()
{
ArticleType = "Newsletter",
ShowDownloadButton = true
};
businessLogicFake.Setup(x => x.FetchPopulatedModel).Returns(model);
//How do I also mock the Sitecore.Context.Item and send it into the constructor, if that's the right approach?
ArticleController controllerUnderTest = new ArticleController(businessLogicFake.Object);
//Act
var result = controllerUnderTest.Index(3) as ViewResult;
//Assert
Assert.IsNotNull(result);
Assert.IsNotNull(result.Model);
}
}
Basically I want to mock a Sitecore.Context.Item, which has a "LinkField" value (referred to as "SitecoreFieldIds.WTW_REDIRECT_TO" above), somehow send it into the controller, and perform the same exact logic as the big if-statement in our original "public override ActionResult Index()" method.
What's the exact code for doing all of this? Thanks!
I highly recommend you to use Sitecore.FakeDb for such purpose which is unit testing framework for Sitecore. So in short words mocking of context item will look like that:
You are coupling your code/logic to static classes that make it difficult to test in isolation. You are also trying to mock code you have no control over.
Encapsulate the desired functionality behind abstraction you control.
The controller would explicitly depend on the service via constructor injection.
The code now has the flexibility to mock dependencies in isolation for unit tests with Moq or any other framework.