如何对 GlassController 操作进行单元测试,其中 Returns 视图采用模型
How to Unit Test a GlassController Action which Returns a View Taking a Model
我是一名 sitecore 开发人员,我想创建一个示例 sitecore helix 单元测试项目来测试我们的 "HomeBottomContentController" 控制器:
public class HomeBottomContentController : GlassController
{
private readonly ISitecoreContext _iSitecoreContext;
public HomeBottomContentController(ISitecoreContext iSitecoreContext)
{
_iSitecoreContext = iSitecoreContext;
}
public override ActionResult Index()
{
var model = _iSitecoreContext.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
}
我创建了一个 WTW.Feature.HomeBottomContent.Tests 项目,目的是使用 helix 单元测试来测试整个组件。在其中我有一个 UnitTest1.cs 文件,其中包含以下内容:
namespace WTW.Feature.HomeBottomContent.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_ISitecoreContextInsertion()
{
var iSitecoreContext = Mock.Of<Glass.Mapper.Sc.ISitecoreContext>();
HomeBottomContentController controllerUnderTest = new HomeBottomContentController(iSitecoreContext);
var result = controllerUnderTest.Index() as ViewResult;
Assert.IsNotNull(result);
}
}
}
这个测试确实通过了,这意味着 "result" 不是空的;但是,问题是当我进入 Index() 代码时,我看到 "model" 变量在我们执行
时为 NULL
var model = _iSitecoreContext.GetCurrentItem<Home_Control>();
我的问题是,我究竟该如何更改此代码以确保该行中的 "model" 不会变为空值?我如何 "mock" _iSitecoreContext 的单元测试代码中的项目,以便它有一个 "Home_Control" 模板,其字段具有合法值?这甚至是正确的方法吗?我发现的大多数在线资源都没有类似的情况,我正在寻找可能的最短代码。
我遇到的另一个问题是,假设 SitecoreContext 是在 inside Index() 方法中声明的,我如何在我的 [TestMethod] 中测试下面的 Index() 方法,而不是像上面那样在 HomeBottomContentController 构造函数中接收?有没有办法从 [TestMethod] 执行此操作,或者我们必须将 SitecoreContext 作为参数发送到 HomeBottomContentController 构造函数或 Index() 方法中?
public override ActionResult Index()
{
var context = new SitecoreContext();
var model = context.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
在这种情况下,您需要在模拟的依赖项上模拟所需的行为
[TestClass]
public class UnitTest1 {
[TestMethod]
public void Test_ISitecoreContextInsertion() {
//Arrange
var model = new Home_Control() {
//...populate as needed
}
var iSitecoreContext = new Mock<Glass.Mapper.Sc.ISitecoreContext>();
//Setup the method to return a model when called.
iSitecoreContext.Setup(_ => _.GetCurrentItem<Home_Control>()).Returns(model);
var controllerUnderTest = new HomeBottomContentController(iSitecoreContext.Object);
//Act
var result = controllerUnderTest.Index() as ViewResult;
//Assert
Assert.IsNotNull(result);
Assert.IsNotNull(result.Model);
//...other assertions.
}
}
更新
在动作中创建上下文会将其与上下文紧密耦合,使其几乎不可能被模拟。这就是注入显式依赖项的原因
你可以这样做:
public class HomeBottomContentController : GlassController
{
private readonly ISitecoreContext _iSitecoreContext;
public HomeBottomContentController(ISitecoreContext iSitecoreContext)
{
_iSitecoreContext = iSitecoreContext;
}
public override ActionResult Index()
{
var model = this.GetCurrentItem();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
protected virtual Home_Control GetCurrentItem()
{
return _iSitecoreContext.GetCurrentItem<Home_Control>();
}
}
namespace WTW.Feature.HomeBottomContent.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_ISitecoreContextInsertion()
{
var iSitecoreContext = Mock.Of<Glass.Mapper.Sc.ISitecoreContext>();
var controllerUnderTest = new FakeHomeBottomContentController(iSitecoreContext);
var result = controllerUnderTest.Index() as ViewResult;
Assert.IsNotNull(result);
}
}
public class FakeHomeBottomContentController : HomeBottomContentController
{
public FakeHomeBottomContentController(ISitecoreContext iSitecoreContext) : base(iSitecoreContext)
{
}
protected override Home_Control GetCurrentItem()
{
// return instance of Home_Control type
// e.g.
return new Home_Control();
}
}
}
我是一名 sitecore 开发人员,我想创建一个示例 sitecore helix 单元测试项目来测试我们的 "HomeBottomContentController" 控制器:
public class HomeBottomContentController : GlassController
{
private readonly ISitecoreContext _iSitecoreContext;
public HomeBottomContentController(ISitecoreContext iSitecoreContext)
{
_iSitecoreContext = iSitecoreContext;
}
public override ActionResult Index()
{
var model = _iSitecoreContext.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
}
我创建了一个 WTW.Feature.HomeBottomContent.Tests 项目,目的是使用 helix 单元测试来测试整个组件。在其中我有一个 UnitTest1.cs 文件,其中包含以下内容:
namespace WTW.Feature.HomeBottomContent.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_ISitecoreContextInsertion()
{
var iSitecoreContext = Mock.Of<Glass.Mapper.Sc.ISitecoreContext>();
HomeBottomContentController controllerUnderTest = new HomeBottomContentController(iSitecoreContext);
var result = controllerUnderTest.Index() as ViewResult;
Assert.IsNotNull(result);
}
}
}
这个测试确实通过了,这意味着 "result" 不是空的;但是,问题是当我进入 Index() 代码时,我看到 "model" 变量在我们执行
时为 NULL var model = _iSitecoreContext.GetCurrentItem<Home_Control>();
我的问题是,我究竟该如何更改此代码以确保该行中的 "model" 不会变为空值?我如何 "mock" _iSitecoreContext 的单元测试代码中的项目,以便它有一个 "Home_Control" 模板,其字段具有合法值?这甚至是正确的方法吗?我发现的大多数在线资源都没有类似的情况,我正在寻找可能的最短代码。
我遇到的另一个问题是,假设 SitecoreContext 是在 inside Index() 方法中声明的,我如何在我的 [TestMethod] 中测试下面的 Index() 方法,而不是像上面那样在 HomeBottomContentController 构造函数中接收?有没有办法从 [TestMethod] 执行此操作,或者我们必须将 SitecoreContext 作为参数发送到 HomeBottomContentController 构造函数或 Index() 方法中?
public override ActionResult Index()
{
var context = new SitecoreContext();
var model = context.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
在这种情况下,您需要在模拟的依赖项上模拟所需的行为
[TestClass]
public class UnitTest1 {
[TestMethod]
public void Test_ISitecoreContextInsertion() {
//Arrange
var model = new Home_Control() {
//...populate as needed
}
var iSitecoreContext = new Mock<Glass.Mapper.Sc.ISitecoreContext>();
//Setup the method to return a model when called.
iSitecoreContext.Setup(_ => _.GetCurrentItem<Home_Control>()).Returns(model);
var controllerUnderTest = new HomeBottomContentController(iSitecoreContext.Object);
//Act
var result = controllerUnderTest.Index() as ViewResult;
//Assert
Assert.IsNotNull(result);
Assert.IsNotNull(result.Model);
//...other assertions.
}
}
更新
在动作中创建上下文会将其与上下文紧密耦合,使其几乎不可能被模拟。这就是注入显式依赖项的原因
你可以这样做:
public class HomeBottomContentController : GlassController
{
private readonly ISitecoreContext _iSitecoreContext;
public HomeBottomContentController(ISitecoreContext iSitecoreContext)
{
_iSitecoreContext = iSitecoreContext;
}
public override ActionResult Index()
{
var model = this.GetCurrentItem();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
protected virtual Home_Control GetCurrentItem()
{
return _iSitecoreContext.GetCurrentItem<Home_Control>();
}
}
namespace WTW.Feature.HomeBottomContent.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_ISitecoreContextInsertion()
{
var iSitecoreContext = Mock.Of<Glass.Mapper.Sc.ISitecoreContext>();
var controllerUnderTest = new FakeHomeBottomContentController(iSitecoreContext);
var result = controllerUnderTest.Index() as ViewResult;
Assert.IsNotNull(result);
}
}
public class FakeHomeBottomContentController : HomeBottomContentController
{
public FakeHomeBottomContentController(ISitecoreContext iSitecoreContext) : base(iSitecoreContext)
{
}
protected override Home_Control GetCurrentItem()
{
// return instance of Home_Control type
// e.g.
return new Home_Control();
}
}
}