2017-09-15 3 views
0

を使用GlassControllerアクションに( )アクションメソッド:どのようにユニットテスト、私はサイトコアの開発者だと私はあなたが私たちの「ArticleControllerは」コントローラのインデックスに見ロジックをテストするためのサンプルサイトコアヘリックスユニットテストプロジェクトを作成したいSitecore.Context.Item

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を、モックとしたい(言及上記の "SitecoreFieldIds.WTW_REDIRECT_TO"として)、何とかコントローラに送信します元の "public override ActionResult Index()"メソッドでbig if-statementと同じ正確なロジックを実行します。

これを実行するための正確なコードは何ですか?ありがとう!

答えて

1

私は非常にあなたがサイトコアのためのユニットテストフレームワークであるそのような目的のためにSitecore.FakeDbを使用することをお勧めします。だから、コンテキスト項目のモック短い言葉でそのようになります。

[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}"); 
    } 
} 
1

あなたはそれが困難な孤立してテストするために作る静的クラスにあなたのコード/ロジックをカップリングされています。また、制御できないコードをモックしようとしています。

制御する抽象化の背後にある目的の機能をカプセル化します。

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); 
    } 
} 

コードは部品番号または任意の他のフレームワークとユニットテストのために分離して依存関係を模擬するための柔軟性を有しています。

関連する問題