我试图找到正确的方法来开始对下面的代码进行单元测试:
public class NameUtility
{
private readonly string _folder = Settings.GetSetting("FolderId");
public ISitecoreDatabase Database {get;set;} = new SitecoreDatabase();
public virtual Path FindById(long Id)
{
var folder = Database.GetItem(new ID(_folder));
var items = folder.GetChildren().Select(child => child.GlassCast<Path>());
return paths.SingleOrDefault(path => path.PathId == Id);
}
}
我对单元测试很陌生,所以我选择了我能找到的最简单的实用程序来测试。这是我的单元测试的开始:
[TestFixture]
public class NameUtilityTests
{
[Test]
public void FindById_WithId_ReturnsPath()
{
var nameUtility = new NameUtility();
nameUtility.Database = new FakeSitecoreDatabase();
var path = nameUtility.FindById(1);
Assert.AreEqual(1, path.PathId);
}
internal class FakeSitecoreDatabase : ISitecoreDatabase
{
public Item GetItem(ID id)
{
throw new System.NotImplementedException();
}
}
}
//Code below is from the Code Under Test assembly.
public interface ISitecoreDatabase
{
Item GetItem(ID id);
}
public class SitecoreDatabase : ISitecoreDatabase
{
private readonly Database _database;
public SitecoreDatabase()
{
_database = Sitecore.Context.Database;
}
public SitecoreDatabase(Database database)
{
_database = database;
}
public Item GetItem(ID id)
{
return _database.GetItem(id);
}
}
所以我有几个问题,我先解释一下我的思考过程。 FindById
目前取决于Sitecore.Context.Database
哪个不适用于单元测试,因此我们使用了SitecoreFakeDb。我没有实现GetItem方法,但我的想法是我使用项目设置SitecoreFakeDb的实例,然后CUT应该能够通过id获取项目。
1)但是,为了测试这段代码,我需要能够用一个FakeDb实例替换Sitecore.Context.Database。为此,我创建了ISitecoreDatabase
,然后它有GetItem()
等方法及其默认(实际)Sitecore数据库将实现的所有重载以及FakeDb。对于接口有多少种方法,这不会开始失控吗?
2)当针对最终对象进行断言时,在这种情况下,我断言所返回的对象具有与我期望的Id相同的字段。这是一种有效的方法,还是将整个实际对象与预期对象进行比较的更好方法?
答案 0 :(得分:0)
一个可用于单元测试的选项Sitecore将使用模拟框架,如Moq。
通过这样做,您可以明确设置每个单元测试,以仅测试适用于您需要测试的项目。这使您不必完全设置数据库,并允许您仅测试每个单元测试中应测试的内容。
以下是您可以编写测试的示例。
private Mock<IMyItemInDatabase> MyItemInDatabaseModel { get; set; };
[TestInitialize]
public void Setup()
{
var mockSitecoreContext = new Mock<ISitecoreContext>();
this.MyItemInDatabaseModel = new Mock<IMyItemInDatabase>();
this.MyItemInDatabaseModel.SetupAllProperties();
mockSitecoreContext.Setup(sc =>sc.GetItem<IMyItemInDatabase
(It.IsAny<string>(), false, false)).
Returns(this.MyItemInDatabaseModel.Object);
}
[TestMethod]
public void MyItemInDatabaseModel_Should_Not_Be_Null()
{
//....perform unit test here
}