简体   繁体   English

如何单元测试一个返回视图的GlassController动作模型

[英]How to Unit Test a GlassController Action which Returns a View Taking a Model

I'm a sitecore developer and I want to create a sample sitecore helix unit testing project for testing out our "HomeBottomContentController" controller: 我是sitecore开发人员,我想创建一个示例sitecore螺旋单元测试项目,用于测试我们的“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);
        }
    }

I have created a WTW.Feature.HomeBottomContent.Tests project, for the purpose of testing this entire component using helix unit testing. 我创建了一个WTW.Feature.HomeBottomContent.Tests项目,目的是使用螺旋单元测试来测试整个组件。 In it I have a UnitTest1.cs file with following: 在其中我有一个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);
        }
    }
}

This test does pass, meaning "result" is NOT null; 此测试确实通过,意味着“结果”不为空; however, the problem is when I step into the Index() code, I see that the "model" variable is NULL when we do 然而,问题是当我进入Index()代码时,我发现当我们这样做时,“model”变量是NULL

    var model = _iSitecoreContext.GetCurrentItem<Home_Control>();

My question is, how exactly do I change this code to make sure that the "model" in that line does not become null? 我的问题是,我究竟如何更改此代码以确保该行中的“模型”不会变为空? How do I "mock" an item in unit test code for the _iSitecoreContext so that it has a "Home_Control" template with legit values for its fields? 如何“模拟”_iSitecoreContext的单元测试代码中的项目,以便它具有一个“Home_Control”模板,其中包含其字段的合法值? Would that even be the right approach? 这甚至是正确的方法吗? Most online sources I've found do not have a similar scenario, I'm looking for the shortest code possible. 我发现的大多数在线资源都没有类似的情况,我正在寻找最短的代码。

Another question I had is, how can I test the below Index() method in my [TestMethod], given that the SitecoreContext is declared inside the Index() method, rather than received in the HomeBottomContentController constructor like above? 我遇到的另一个问题是,如果SitecoreContext是 Index()方法中声明的,而不是像上面那样在HomeBottomContentController构造函数中接收,我如何在我的[TestMethod]中测试下面的Index()方法? Is there a way to do that from the [TestMethod], or we have to send in the SitecoreContext into the HomeBottomContentController constructor or into the Index() method as a parameter? 有没有办法从[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);
}

In that case you would need to mock the desired behavior on the mocked dependency 在这种情况下,您需要在模拟的依赖项上模拟所需的行为

[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.
    }
}

UPDATE UPDATE

Creating the context within the action tightly couples it to the context, making it almost impossible to mock. 在动作中创建上下文将其紧密地耦合到上下文,使得几乎不可能模拟。 That is the reason explicit dependencies are injected 这就是注入显式依赖的原因

You can do something like that: 你可以这样做:

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();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何对使用Sitecore.Context.Item的GlassController动作进行单元测试 - How to Unit Test a GlassController Action which Uses Sitecore.Context.Item 如何在没有SitecoreContext依赖项注入的情况下对GlassController动作进行单元测试 - How to Unit Test a GlassController Action without SitecoreContext Dependency Injection 如何对返回 JsonResult 的 Action 方法进行单元测试? - How to unit test an Action method which returns JsonResult? 如何为返回十进制的 IActionResult 控制器操作创建单元测试? - How to create a unit test for an IActionResult controller action which returns decimal? 如何对返回Action的方法进行单元测试 <AuthenticationOptions> ? - How to unit test a method that returns Action<AuthenticationOptions>? 如何对返回函数的字典进行单元测试? - How to unit test a dictionary which returns a func? 我如何单元测试返回PartialViewResult的MVC Action? - How can I unit test an MVC Action that returns a PartialViewResult? 如何在WPF中对Test View模型和Mvvm应用程序模型进行单元测试 - How to Unit Test View Model and Model of a Mvvm application in wpf 如何对返回 ToList 的操作进行单元测试 - How do I unit test an action that returns a ToList 在单元测试中返回视图模型 - Return View Model in Unit Test
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM