我是Sitecore开发人员,我想创建一个示例Sitecore Helix单元测试项目,以测试您在我们的" ARTICLECONTROLLER"中看到的逻辑,P>
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);
}
}
这是我在单元测试类中所拥有的:
[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);
}
}
基本上,我想模拟一个具有" linkField"值的sitecore.context.item(上面称为" sitecorefieldss.wtw_redirect_to"),以某种方式将其发送到控制器中,并执行与大型逻辑相同的逻辑如果在我们的原始"公共覆盖ActionResult index()"方法中说明。
做所有这些的确切代码是什么?谢谢!
您将代码/逻辑与静态类耦合,这使得很难隔离测试。您还试图模拟代码,您无法控制。
封装了您控制的抽象背后的所需功能。
public interface IArticleRedirectService {
Url CheckUrl();
}
public class ArticleRedirectionService : IArticleRedirectionService {
public Url CheckUrl() {
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 Sitecore.Links.LinkManager.GetItemUrl(link.TargetItem);
} else {
return link.Url;
}
}
}
return null;
}
}
控制器将通过构造仪注入明确取决于服务。
public class ArticleController : GlassController {
private readonly IArticleBusiness businessLogic;
private readonly IArticleRedirectionService redirect;
public ArticleController(IArticleBusiness businessLogic, IArticleRedirectionService redirect) {
this.businessLogic = businessLogic;
this.redirect = redirect;
}
public ActionResult Index() {
// If a redirect has been configured for this Article,
// then redirect to new location.
var url = redirect.CheckUrl();
if(url != null) {
return Redirect(url);
}
var model = businessLogic.FetchPopulatedModel;
return View("~/Views/EmailCampaign/EmailArticle.cshtml", model);
}
}
现在,代码可以灵活地模拟使用MOQ或任何其他框架的单位测试的依赖项。
我强烈建议您将Sitecore.fakedb用于此目的,这是Sitecore的单元测试框架。因此,简而
[TestCase]
public void FooActionResultTest()
{
// arrange
var itemId = ID.NewID;
using (var db = new Db
{
new DbItem("Some Item", itemId)
{
new DbField(SitecoreFieldIds.WTW_REDIRECT_TO) { Value = "{some-raw-value}" }
}
})
{
// act
Sitecore.Context.Item = db.GetItem(itemId);
// assert
Sitecore.Context.Item[SitecoreFieldIds.WTW_REDIRECT_TO].Should().Be("{some-raw-value}");
}
}