하지

0

내가 GlassMapperORMTDS를 사용하는 기존 Sitecore 프로젝트 에 MVC5에 대한 단위 테스트를 작성하는 것을 시도하고 테스트 . Jeff Sulit의 매우 유익한 블로그 게시물을 사용하여 Sitecore Content Tree, Sitecore Context, Item Properties, Field Collections 및 Base Item을 조롱했습니다. 하지

https://oddeven.ch/blog/mocking-sitecore-using-ms-fakes/

는 이제 위의 게시물에 설정 한 설정 (위 .... 에 응답하기 전에 그것을 통해 이동하시기 바랍니다 링크로 공유). 위의 설정을 별도의 클래스 파일 UnitTestAssist.cs 내 비즈니스 계층에 보관했습니다.

지금 나는 내 단위 테스트 프로젝트에서 가짜 항목을 만든 다음 null를 돌려 Sitecore.Context, Database.GetItem 호출에 의해 UnitTestAssist 클래스 객체의 객체를 통해 액세스하는 다음과 같은 기본 단위 테스트를 작성했습니다 .

namespace MySiteCoreUnitTest 
{ 
[TestClass] 
public class DataFetch 
{ 
    IDisposable _context; 
    readonly MySiteCoreUnitTest.UnitTestAssist _scFaker = new MySiteCoreUnitTest.UnitTestAssist(); 

    [TestInitialize] 
    public void Initialize() 
    { 
     _context = ShimsContext.Create(); 
     _scFaker.Initialize(); 
    } 

    [TestCleanup] 
    public void Cleanup() 
    { 
     _context.Dispose(); 
    } 

    [TestMethod] 
    public void TestingDataFetch() 
    { 
     List<ShimField> lstfields = new List<ShimField>();    

     //Arrange 

     ShimField dummyField = new ShimField() 
     { 
      IDGet =() => ID.NewID, 
      NameGet =() => "Ava_Title", 
      ValueGet =() => "This is fucking Crazy" 
     }; 

     lstfields.Add(dummyField); 

     var expectedItem = _scFaker.CreateFakeItem(_scFaker.Home, "sample item", (itemName, inputField) => { inputField = lstfields; }); 

     // Act: 
     var actualItem = Context.Database.GetItem(expectedItem.Instance.Paths.FullPath); 
     var actualItemFields = actualItem.Fields; // On Debugging i get the field i added forcefully inside **UnitTestAssist**. 

     // Assert: 
     Assert.AreEqual(expectedItem, actualItem); 

    } 

} 
} 

다음은 모의 아이템을 만드는 데 사용한 코드입니다.

namespace MySiteCoreUnitTest 
{ 
public class UnitTestAssist 
{ 
    private readonly Language ContextLanguage = Language.Parse("en"); 

    ShimItem CreateFakeItem(ShimItem parentItem, string name, Action<ShimItem, ShimTemplateItem, List<ShimField>> onItemCreating) 
    { 
     var id = ID.NewID; 

     var item = new ShimItem() 
     { 
      // Assigning ID.NewID directly will return a new ID every time item.ID is called 
      IDGet =() => id, 
      KeyGet =() => name.ToLower(), 
      NameGet =() => name, 
      HasChildrenGet =() => false, 
      ParentGet =() => parentItem, 
      PathsGet =() => 
      { 
       var path = (parentItem != null ? parentItem.Instance.Paths.Path : "") + "/" + name; 

       return new ShimItemPath() 
       { 
        PathGet =() => path, 
        FullPathGet =() => path, 
       }; 
      }, 
      LanguageGet =() => ContextLanguage, 
      VersionsGet =() => new ShimItemVersions() { CountGet =() => { return 1; } } 
     }; 

     // Bind item to parent item 
     if (parentItem != null) 
     { 
      var children = parentItem.Instance.HasChildren ? parentItem.Instance.Children.ToList() : new List<Item>(); 
      children.Add(item); 

      parentItem.HasChildrenGet =() => true; 
      parentItem.ChildrenGet =() => new ChildList(parentItem.Instance, children); 
      parentItem.GetChildren =() => parentItem.Instance.Children; 
     } 

     // Start faking template and field collection 
     var templateItem = new ShimTemplateItem(); 
     var field = new ShimField 
     { 

     }; 
     //var fields = new List<ShimField>(); 

     List<ShimField> fields = new List<ShimField>(); 

     //Arrange 
     ShimField dummyField = new ShimField() 
     { 
      IDGet =() => ID.NewID, 
      NameGet =() => "Ava_Title", 
      ValueGet =() => "This is fucking Crazy" 
     }; 

     fields.Add(dummyField); 

     // Call action to allow extension of item, template, and field collection faking  
     onItemCreating(item, templateItem, fields); 

     item.TemplateGet =() => templateItem; 
     item.FieldsGet =() => CreateFakeFieldCollection(item, fields); 

     return item; 
    } 

    // Create a dictionary to hold the field collection per item ID 
    private Dictionary<ID, List<ShimField>> itemFields = new Dictionary<ID, List<ShimField>>(); 

    ShimFieldCollection CreateFakeFieldCollection(ShimItem item, List<ShimField> fields) 
    { 
     foreach (var field in fields) 
      field.ItemGet =() => item; 

     ShimField _newField = new ShimField(); 

     var fieldCollection = new ShimFieldCollection() 
     { 
      ItemGetString = (fieldName) => 
      { 
       _newField = fields.SingleOrDefault(n => n.Instance.Name.Equals(fieldName, StringComparison.OrdinalIgnoreCase)); 
       return fields.SingleOrDefault(n => n.Instance.Name.Equals(fieldName, StringComparison.OrdinalIgnoreCase)); 

      } 
     }; 

     Field testField = _newField; 

     if (!itemFields.ContainsKey(item.Instance.ID)) 
       itemFields.Add(item.Instance.ID, fields); 

     else 
      itemFields[item.Instance.ID] = fields; 

     fieldCollection.Bind(itemFields[item.Instance.ID]); 

     return fieldCollection; 
    } 

    void FakeSitecoreContext() 
    { 
     ShimContext.LanguageGet =() => ContextLanguage; 
     ShimContext.SiteGet =() => new ShimSiteContext() 
     { 
      ContentLanguageGet =() => ContextLanguage 
     }; 

     Func<Func<Item, bool>, Item> getItem = (predicate) => 
     { 
      Item result; 

      return TryGetItem(this.Sitecore.Instance.Children, predicate, out result) ? result : null; 
     }; 

     ShimContext.DatabaseGet =() => new ShimDatabase() 
     { 
      GetItemString = (path) => getItem(n => n.Paths.Path.Equals(path, StringComparison.OrdinalIgnoreCase)), 
      GetItemStringLanguage = (path, lang) => getItem(n => n.Paths.Path.Equals(path) && (n.Language.Equals(lang) || n.Languages != null && n.Languages.Any(l => l.Name.Equals(lang.Name)))), 
      GetItemID = (id) => getItem(n => n.ID.Equals(id)), 
      GetItemIDLanguage = (id, lang) => getItem(n => n.ID.Equals(id) && (n.Language.Equals(lang) || n.Languages != null && n.Languages.Any(l => l.Name.Equals(lang.Name)))), 
     }; 
    } 

    bool TryGetItem(ChildList children, Func<Item, bool> predicate, out Item result) 
    { 
     result = null; 

     if (children == null || !children.Any()) return false; 

     result = children.FirstOrDefault(predicate); 

     if (result != null) return true; 

     var query = children.Where(n => n.HasChildren); 

     if (!query.Any()) return false; 

     foreach (var child in query.ToArray()) 
     { 
      if (TryGetItem(child.Children, predicate, out result)) 
       return true; 
     } 

     return false; 
    } 

    void FakeBaseItem() 
    { 
     ShimBaseItem.AllInstances.ItemGetString = (baseItem, fieldName) => 
     { 
      Item result; 

      TryGetItem(Sitecore.Instance.Children, (n) => object.Equals(baseItem, n), out result); 

      if (result != null) 
      { 
       var fields = itemFields[result.ID]; 

       var field = fields.FirstOrDefault(n => n.Instance.Name.Equals(fieldName, StringComparison.OrdinalIgnoreCase)); 

       if (field != null) return field.Instance.Value; 
      } 

      return string.Empty; 
     }; 
    } 

    public ShimItem Sitecore, Content, Site, Home; 
    public void Initialize(Action<UnitTestAssist> onInitializing = null) 
    {   

     Sitecore = CreateFakeItem(null, "sitecore", (sitecore, someFieldSitecore) => 
     { 
      Content = CreateFakeItem(sitecore, "content", (content, someFieldContent) => 
      { 
       Site = CreateFakeItem(content, "site", (site, someFieldSite) => 
       { 
        Home = CreateFakeItem(site, "home", (home, someFieldHome) => 
        { 
         // Add more items if you must to mimic your Sitecore tree 
        }); 
       }); 
      }); 
     }); 

     if (onInitializing != null) 
      onInitializing(this); 

     FakeBaseItem(); 
     FakeSitecoreContext(); 
    } 

    public ShimItem CreateFakeItem(ShimItem parentItem, string name, Action<ShimItem,List<ShimField>> onItemCreating) 
    { 
     return CreateFakeItem(parentItem, name, (i, t, f) => 
     { 
      if (onItemCreating != null) 
       onItemCreating(i,f); 
     }); 
    } 
} 
} 

는 내가 단위 테스트에서 인수로 List<ShimField>을 받아 들일 수 있도록 제프의 코드를 수정하지만 여전히 널 항목 필드를 보냅니다. 제프, 도와 줄 수있어?

답변

0

'UnitTestHelperClass'클래스의 실제 코드를 보지 않고 말하기가 어렵습니다. 아마도 당신이 그것을 공유 할 수 있다면 아마도 도움이 될 것입니다.

UPDATE

:

var expectedItem = _scFaker.CreateFakeItem(_scFaker.Home, "sample item", (itemName, inputField) => { inputField.AddRange(lstfields); });

+0

안녕 제프, 당신이 응답에 필요한 코드를 추가 한 : 나는 당신의 문제를 해결하기 위해 코드를 리팩토링했습니다. 당신의 도움을 주셔서 감사합니다. –

+0

안녕하세요 제프 Sitecore 8.1.3을 사용하고 있습니다. 이 코드를 사용하여 FakeFieldCollection을 성공적으로 생성하고 액세스 할 수 있었습니까? CreateFakeItem 메서드 오버로드에서 입력을 제공 할 때 작동해야하는 동안 FieldCollection을 생성하고 가져 오는 UnitTestAssist 내부의 shimfield 목록을 하드 코딩해야했습니다. –

+0

안녕하세요 Nitin! ShimField를 두 번 추가했습니다 : 하나는 faker 클래스에, 하나는 unittest에 추가되었습니다. 너는 faker 클래스에서 그걸 제거하고 싶을지도 모른다. 어쨌든 항목 (예 : actualItem [ "Ava_Title"])에서 필드의 값을 가져 오려고 할 때 필드 값을 가져올 수 있습니다. 대신 필드 값을이 방식으로 가져올 수 있도록 테스트를 변경할 수 있습니까? –