IHttpActionResult匿名对象 - 验证结果
IHttpActionResult匿名对象 - 验证结果
我正在尝试为我们的Web API调用创建一个测试,但是在访问结果时遇到了困难。在我查看的所有示例中,它们都在使用OkNegotiatedContentResult。问题在于,在我们的Web API调用中,我们经常将数据包装在匿名对象中,以便我们可以组合数据集。我可能忽视了一些明显的东西,但我似乎无法找到验证结果信息的正确方法。\nWeb API片段:\nvar orderInfo = new\n{\n Customer = customerInfo,\n Order = orderInfo\n}\nreturn Ok(orderInfo);\nAPI测试片段:\n[TestMethod]\npublic void TestGetOrderInfo()\n{\n var controller = new OrderController(_repo);\n IHttpActionResult results = controller.GetOrderInfo(46);\n Assert.IsNotNull(results);\n}\n当涉及匿名类型时,我该如何使用OkNegotiatedContentResult来检查结果?
问题:为什么会出现 "object' does not contain a definition for 'Content'" 错误,并提供解决方法。
原因:出现该错误的原因是被测试的项目生成的匿名类型是internal的,而测试项目无法访问internal类型。因此,需要在被测试的项目的AssemblyInfo.cs文件中添加[assembly: InternalsVisibleTo("Tests.Unit")]
,以将internal类型暴露给测试项目。
解决方法:在被测试的项目的AssemblyInfo.cs文件中添加[assembly: InternalsVisibleTo("Tests.Unit")]
,以将internal类型暴露给测试项目。这样测试项目就能够访问并检查匿名类型了。
参考文章:在这篇文章中发现了这个解决方法:http://patrickdesjardins.com/blog/how-to-unit-test-a-method-that-return-an-anonymous-type
匿名对象是由创建它们的程序集内部使用的。如果您在一个单独的程序集(DLL)中进行单元测试,您需要使用InternalsVisibleTo属性明确表示您希望与该程序集共享内部值。
在进行单元测试时,有时我们需要测试一些内部方法或属性,这些方法或属性在程序集外部是不可访问的。而匿名对象就是其中一种常见的内部对象类型。但是,当我们在一个单独的程序集中进行单元测试时,我们会发现无法访问或使用匿名对象。
这是因为匿名对象是内部的,只能在创建它们的程序集中使用。为了解决这个问题,我们需要使用InternalsVisibleTo属性来明确表示我们希望与该程序集共享内部值。
InternalsVisibleTo属性是一个程序集级别的属性,它允许我们将内部成员暴露给指定的程序集。通过在要访问匿名对象的程序集中添加InternalsVisibleTo属性,我们可以轻松地访问和使用这些内部对象。
下面是一个示例代码,演示了如何使用InternalsVisibleTo属性来解决无法访问匿名对象的问题:
// 在创建匿名对象的程序集中添加InternalsVisibleTo属性 [assembly: InternalsVisibleTo("UnitTestAssembly")] // 在单元测试的程序集中访问匿名对象 namespace UnitTestAssembly { public class UnitTest { [Fact] public void TestAnonymousObject() { // 创建匿名对象 var anonymousObject = new { Name = "John", Age = 25 }; // 访问匿名对象的属性 var name = anonymousObject.Name; var age = anonymousObject.Age; // 断言测试结果 Assert.Equal("John", name); Assert.Equal(25, age); } } }
在上面的示例中,我们在创建匿名对象的程序集中添加了InternalsVisibleTo属性,并指定了单元测试的程序集名称。这样,我们就可以在单元测试的程序集中访问和使用匿名对象。
通过使用InternalsVisibleTo属性,我们可以解决无法访问匿名对象的问题,并在单元测试中对其进行验证。这样,我们就可以确保匿名对象的行为和结果符合预期。
匿名类型的问题是由于它们是内部类型而不是公共类型,所以无法在测试中使用它们。
如果在WebAPI项目中添加InternalsVisibleTo属性,就可以通过dynamic引用结果及其内容,例如:
[TestMethod] public void TestGetOrderInfo() { var controller = new OrderController(_repo); dynamic results = controller.GetOrderInfo(46); dynamic content = results.Content; ... }
我遇到了与匿名类型和IHttpActionResult相同的问题。我必须在JSON返回中添加一个根节点,所以我在Web API 2.0中使用`return Json(new { User = person });`来在返回结果中添加名为"User"的根节点。这样就返回了一个匿名类型。我尝试按照你的示例进行操作,但在`dynamic content = results.Content`处报错`'object' does not contain a definition for 'Content'`。
这对我有所帮助,但随后我遇到了一个编译器错误"Missing compiler required member 'microsoft.csharp.runtimebinder.binder.convert'",这让我想到了stackoverflow.com/a/50050820/283895,现在问题已经解决了。
我只想说,使用dynamic真的太丑陋了。如果你真的需要这样做,最好创建一个返回ContentResult类型的类。