5

所以我有一个控制器,可以将 json 返回到我需要测试的视图中。我曾尝试使用具有动态数据类型的反射来访问列表的子属性,但我不断收到类似于“无法投射”错误的内容。基本上我在一个列表中有一个列表,我想访问和验证有关但我无法访问它的内容。有没有人在 MVC4 中测试过从他们的控制器返回的 json 并有建议?

代码:

// arrange
        var repositoryMock = new Mock<IEdwConsoleRepository>();
        var date = -1;
        var fromDate = DateTime.Today.AddDays(date);
        EtlTableHistory[] tableHistories =
            {
                new EtlTableHistory
                    {
                        Table = new Table(),
                        RelatedStatus = new BatchStatus(),
                        BatchId = 1
                    }
            };
        EtlBatchHistory[] batchHistories = { new EtlBatchHistory
                                             {
                                                 Status = new BatchStatus(),
                                                 TableHistories = tableHistories
                                             } };

        repositoryMock.Setup(repository => repository.GetBatchHistories(fromDate)).Returns((IEnumerable<EtlBatchHistory>)batchHistories);
        var controller = new EdwController(new Mock<IEdwSecurityService>().Object, repositoryMock.Object);

        // act
        ActionResult result = controller.BatchHistories(1);

        // assert
        Assert.IsInstanceOfType(result, typeof(JsonResult), "Result type was incorrect");
        var jsonResult = (JsonResult)result;
        var resultData = (dynamic)jsonResult.Data;
        var returnedHistories = resultData.GetType().GetProperty("batchHistories").GetValue(resultData, null);

        var returnedTableHistoriesType = returnedHistories.GetType();
        Assert.AreEqual(1, returnedTableHistoriesType.GetProperty("Count").GetValue(returnedHistories, null), "Wrong number of logs in result data");
4

2 回答 2

3

这是一个例子:

Controller:

    [HttpPost]
    public JsonResult AddNewImage(string buildingID, string desc)
    {
        ReturnArgs r = new ReturnArgs();

        if (Request.Files.Count == 0)
        {
            r.Status = 102;
            r.Message = "Oops! That image did not seem to make it!";
            return Json(r);
        }
        if (!repo.BuildingExists(buildingID))
        {
            r.Status = 101;
            r.Message = "Oops! That building can't be found!";
            return Json(r);
        }

        SaveImages(buildingID, desc);
        r.Status = 200;
        r.Message = repo.GetBuildingByID(buildingID).images.Last().ImageID;

        return Json(r);
    }

    public class ReturnArgs
    {
        public int Status { get; set; }
        public string Message { get; set; }
    }

Test:

    [TestMethod]
    public void AddNewImage_Returns_Error_On_No_File()
    {
        // Arrange
        ExtendedBuilding bld = repo.GetBuildings()[0];
        string ID = bld.Id;

        var fakeContext = new Mock<HttpContextBase>();
        var fakeRequest = new Mock<HttpRequestBase>();

        fakeContext.Setup(cont => cont.Request).Returns(fakeRequest.Object);
        fakeRequest.Setup(req => req.Files.Count).Returns(0);

        BuildingController noFileController = new BuildingController(repo);
        noFileController.ControllerContext = new ControllerContext(fakeContext.Object, new System.Web.Routing.RouteData(), noFileController);

        // Act
        var result = noFileController.AddNewImage(ID, "empty");

        ReturnArgs data = (ReturnArgs)(result as JsonResult).Data;

        // Assert
        Assert.IsTrue(data.Status == 102);
    }

在您的示例中,在我看来问题出在此处:

var resultData = (dynamic)jsonResult.Data;
var returnedHistories = resultData.GetType().GetProperty("batchHistories").GetValue(resultData, null);

resultData 对象将是您在操作中返回的对象的确切类型。因此,如果您执行以下操作:

List<String> list = repo.GetList();
return Json(list);

然后你的 resultData 将是类型:

List<String>

尝试确保您使用 Json(obj) 函数返回您的对象。

于 2013-09-27T08:44:29.780 回答
0

您可以将您的 Json 反序列化为动态对象,然后询问您想要的属性

例子:

dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

var propertyValue = obj.MyProperty; //Ask for the right property

您可以从 Nuget Json.Net 包中添加 Json 序列化程序。

于 2013-09-26T15:22:39.367 回答