如何在MSTest中对JsonResult和集合进行单元测试

时间:2011-11-29 22:47:26

标签: asp.net-mvc unit-testing mstest

即使我已经编码了很长时间,我对单元测试也很陌生。我想把它作为我发展方式的一部分。我遇到了关于如何对集合进行单元测试的问题。我通常有我的jQuery脚本调用ASP.Net Server方法来获取数据和填充表格等。他们看起来像

Get_*Noun*() 

通常返回JsonResult。关于使用MSTest进行单元测试的测试方法和方法的任何想法?

6 个答案:

答案 0 :(得分:52)

如果可以从JsonResult中提取值,您应该能够像其他任何东西一样测试它。这是一个帮助你的帮手:

private T GetValueFromJsonResult<T>(JsonResult jsonResult, string propertyName)
{
    var property =
        jsonResult.Data.GetType().GetProperties()
        .Where(p => string.Compare(p.Name, propertyName) == 0)
        .FirstOrDefault();

    if (null == property)
        throw new ArgumentException("propertyName not found", "propertyName");
    return (T)property.GetValue(jsonResult.Data, null);
}

然后像往常一样调用控制器,并使用该帮助程序测试结果。

var jsonResult = yourController.YourAction(params);
bool testValue = GetValueFromJsonResult<bool>(jsonResult, "PropertyName");
Assert.IsFalse(testValue);

答案 1 :(得分:19)

(我使用的是NUnit语法,但MSUnit不应该太远)

您可以像这样测试您的JsonResult:

var json = Get_JsonResult()
dynamic data = json.Data;
Assert.AreEqual("value", data.MyValue)

然后在包含要测试的代码的项目中,编辑AssemblyInfo.cs文件以允许测试程序集访问匿名类型:

[assembly: InternalsVisibleTo("Tests")]

动态可以确定从json.Data值返回的匿名对象的类型;

答案 2 :(得分:3)

This是我在这个主题上找到的最好的博客。

我最喜欢的是使用动力学的第四种方法。请注意,它要求您确保使用[assembly:InternalsVisibleTo("TestProject")]对您的测试项目显示内部结构,我发现这是一个相当不错的主意。

[TestMethod]     
public void IndexTestWithDynamic()     
{     
    //arrange     
    HomeController controller = new HomeController();     

    //act     
    var result = controller.Index() as JsonResult;     

    //assert     
    dynamic data = result.Data;  

    Assert.AreEqual(3, data.Count);     
    Assert.IsTrue(data.Success);     
    Assert.AreEqual("Adam", data.People[0].Name);     
}

答案 3 :(得分:2)

您可以使用PrivateObject执行此操作。

var jsonResult = yourController.YourAction(params);
var success = (bool)(new PrivateObject(jsonResult.Data, "success")).Target;
Assert.IsTrue(success);

var errors = (IEnumerable<string>)(new PrivateObject(jsonResult.Data, "errors")).Target;
Assert.IsTrue(!errors.Any());

它使用的反射类似于David Ruttka的回答,但它会为你节省几笔关键。

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.privateobject.aspx

答案 4 :(得分:0)

Here's a small extension可以轻松地将Json ActionResult转换为它所代表的对象。

using System.Web.Mvc;

public static class WebExtensions
{
     public static T ToJson<T>(this ActionResult actionResult)
     {
         var jsonResult = (JsonResult)actionResult;

         return (T)jsonResult.Data;
     }
}

有了这个,你在测试中的'行为'变得更小了:

var myModel = myController.Action().ToJson<MyViewModel>();

答案 5 :(得分:0)

我的建议是为返回的数据创建一个模型,然后将结果转换为该模型。这样你就可以验证:

  1. 结构正确
  2. 模型中的数据是正确的

    // Assert
    var result = action
        .AssertResultIs<JsonResult>();
    
    var model = (UIDSearchResults)result.Data;
    Assert.IsTrue(model.IsValid);
    Assert.AreEqual("ABC", model.UIDType);
    Assert.IsNull(model.CodeID);
    Assert.AreEqual(4, model.PossibleCodes.Count());