0

我想要編寫單元測試現有Sitecore的項目上MVC5使用GlassMapperORMTDS 。我嘲笑了Sitecore內容樹,Sitecore上下文,項目屬性,字段集合和基本項目,使用Jeff Sulit的這個非常有用的博客文章。無法通過在單位Sitecore的上下文來訪問Sitecore的模擬項目(MS正版正貨)測試

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

目前已在上述職位的設置(如共享以上鍊接.... 請通過它去回答之前)。我已將上述設置保存在我的業務層的單獨的類文件UnitTestAssist.cs中。

現在我已經寫在我從我的單元測試項目創建一個假物品,然後通過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'類的實際代碼。如果你也可以分享它,也許它會很有用。

更新: 我已經重構你的代碼來解決此問題:

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

+0

喜傑夫,我加你需要回答的代碼。感謝你的幫助。 –

+0

嗨,Jeff,我正在使用Sitecore 8.1.3。您是否能夠使用這段代碼成功創建並訪問FakeFieldCollection?我必須硬編碼UnitTestAssist中的shimfield列表來生成和獲取fieldcollection,同時它應該在我提供來自CreateFakeItem方法重載的輸入時起作用。 –

+0

嗨尼廷!我注意到你已經添加了兩次ShimField:一個在你的faker類和一個在你的單元測試中。你可能想刪除faker類中的那個。無論如何,當我嘗試從項目中獲取字段值時(例如actualItem [「Ava_Title」]),我可以檢索該字段的值。你可以改變你的測試,以便這樣獲得字段值嗎? –

相關問題