내가 GlassMapperORM 및 TDS를 사용하는 기존 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>
을 받아 들일 수 있도록 제프의 코드를 수정하지만 여전히 널 항목 필드를 보냅니다. 제프, 도와 줄 수있어?
안녕 제프, 당신이 응답에 필요한 코드를 추가 한 : 나는 당신의 문제를 해결하기 위해 코드를 리팩토링했습니다. 당신의 도움을 주셔서 감사합니다. –
안녕하세요 제프 Sitecore 8.1.3을 사용하고 있습니다. 이 코드를 사용하여 FakeFieldCollection을 성공적으로 생성하고 액세스 할 수 있었습니까? CreateFakeItem 메서드 오버로드에서 입력을 제공 할 때 작동해야하는 동안 FieldCollection을 생성하고 가져 오는 UnitTestAssist 내부의 shimfield 목록을 하드 코딩해야했습니다. –
안녕하세요 Nitin! ShimField를 두 번 추가했습니다 : 하나는 faker 클래스에, 하나는 unittest에 추가되었습니다. 너는 faker 클래스에서 그걸 제거하고 싶을지도 모른다. 어쨌든 항목 (예 : actualItem [ "Ava_Title"])에서 필드의 값을 가져 오려고 할 때 필드 값을 가져올 수 있습니다. 대신 필드 값을이 방식으로 가져올 수 있도록 테스트를 변경할 수 있습니까? –