代码之家  ›  专栏  ›  技术社区  ›  Elisabeth

返回json的非常小的asp.net mvc操作的单元测试

  •  0
  • Elisabeth  · 技术社区  · 12 年前

    我的第一行操作是用一个额外的集成测试来测试的。 第二行是针对automapper映射的额外单元测试 第三条线还没有经过测试。

    下面的单元测试是测试第三行吗?因为它只是测试返回类型。

    这似乎太愚蠢或太琐碎了。该方法还应该返回什么????

    此操作中没有if/else逻辑。因此,仅仅测试类型==JsonNetResult对我来说似乎是超流畅的。如果有人删除success=true匿名类型,我甚至不会在单元测试中意识到这一点。

    我应该用QUnit测试JsonNetResult的数据吗?

    我很高兴能得到一些指导和提示,因为返回Json数据的行为让我抓狂。。。它只是从数据库中获取数据并将其放入JsonNetResult对象中。

    行动

    [HttpGet]
    public ActionResult GetTemplateRootUnits(int templateId)
    {
        IEnumerable<Unit> units = _dataProvider.GetTemplateRootUnits(templateId);
        IEnumerable<UnitTreeViewModel> unitTreeViewModels = Mapper.Map<IEnumerable<Unit>, IEnumerable<UnitTreeViewModel>>(units);
        return new JsonNetResult(new { data = unitTreeViewModels, success = true });
    }
    

    单元测试

    [Test]
    public void GetTemplateRootUnits_TemplateExists_ReturnsJsonNetResult()
    {
        // ARRANGE  
        Mock<IUnitDataProvider> mock1 = new Mock<IUnitDataProvider>();
        Mock<IMappingEngine> mock2 = new Mock<IMappingEngine>();
        Mock<ControllerContext> mock3 = new Mock<ControllerContext>();
        UnitController controller = new UnitController(mock1.Object, mock2.Object);
        mock1.Setup(m => m.GetTemplateRootUnits(1)).Returns(new List<Unit> 
        { 
            new Unit{ UnitId = 1, Name = "Name1", HasChildren = false},
            new Unit{ UnitId = 2, Name = "Name2", HasChildren = false},
            new Unit{ UnitId = 3, Name = "Name3", HasChildren = false},
        });
    
        var unitTreeViewModels = new List<UnitTreeViewModel> 
        { 
            new UnitTreeViewModel { Id = 1, Name = "Name1", HasChildren = false},
            new UnitTreeViewModel { Id = 2, Name = "Name2", HasChildren = false},
            new UnitTreeViewModel { Id = 3, Name = "Name3", HasChildren = false},
        };
    
        // Thats the way AutoMapper is mocked
        mock2.Setup(m => m.Map<IEnumerable<Unit>, IEnumerable<UnitTreeViewModel>>(It.IsAny<IEnumerable<Unit>>())).Returns(unitTreeViewModels);
    
        // ACT
        ActionResult result = controller.GetTemplateRootUnits(1);
    
        // ASSERT - check that the dataProvider.GetTestplanRootUnits() was called
        mock1.Verify(m => m.GetTemplateRootUnits(1));
    
        // ASSERT
        Assert.IsInstanceOfType(typeof(JsonNetResult), result);
    } 
    

    JsonNetResult.cs

    public class JsonNetResult : ContentResult
        {
            private readonly object _data;
            public JsonNetResult(object data)
            {
                _data = data;
            }
    
            public override void ExecuteResult(ControllerContext context)
            {
                Content = JsonConvert.SerializeObject(_data);
                ContentType = "application/json";
                base.ExecuteResult(context);
            }
            public object Data { get { return _data; } }
        }
    
    2 回复  |  直到 12 年前
        1
  •  0
  •   Darin Dimitrov    12 年前

    你还没有展示 JsonNetResult 类,但我假设它是使用JSON.NET作为序列化程序而不是默认的JavaScriptSerializer的一些自定义操作结果。我还假设这个类公开了一个名为 Data 持有要被序列化的模型:

    public class JsonNetResult: ActionResult
    {
        public JsonNetResult(object data)
        {
            Data = data;
        }
        public object Data { get; private set; }
    
        ...
    }
    

    因此,您可以测试结果中的数据:

    // ASSERT
    Assert.IsInstanceOfType(typeof(JsonNetResult), result);
    
    var jsonResult = result as JsonNetResult;
    var data = new RouteValueDictionary(jsonResult.Data);
    Assert.IsTrue((bool)data["success"]);
    Assert.IsInstanceOfType(data["data"], typeof(IEnumerable<UnitTreeViewModel>));
    Assert.AreEqual(unitTreeViewModels, data["data"]);
    
        2
  •  0
  •   Kirill Bestemyanov    12 年前

    您不需要测试返回值的类型。您需要在方法的签名中设置返回值的类型。

    public JsonNetResult GetTemplateRootUnits(int templateId);