gpt4 book ai didi

c# - 如何对返回匿名对象的 ASP.NET Core MVC Controller 进行单元测试?

转载 作者:太空狗 更新时间:2023-10-29 17:33:57 24 4
gpt4 key购买 nike

我在对返回匿名对象的 ASP.NET Core MVC Controller 进行单元测试时遇到问题。单元测试设置在一个单独的项目中,并直接从主项目调用 Controller 方法。

Controller 方法返回 IActionResult 但通常这些是 OkObjectResultBadRequestObjectResult 对象,它们被转换为具有适当 HTTP 状态代码的 JSON 响应.匿名对象作为 ObjectResult 对象的构造函数参数传递,我试图针对这些对象进行断言(可通过 ObjectResult.Value 访问)。

我发现这个问题(how can i access internals in asp.net 5)的答案是使用动态并添加

[assembly: InternalsVisibleTo("Namespace")]

到 AssemblyInfo.cs 以允许测试项目访问匿名对象的内部对象属性。但是,最新版本的 ASP.NET Core MVC 没有 AssemblyInfo.cs,并且按照链接问题的答案中的建议添加一个也不起作用。

现在是否有不同的位置来添加 InternalsVisibleTo 还是我遗漏了什么?

最佳答案

来自 this answer 的原创想法用更通用的方法。使用自定义 DynamicObject 作为通过反射检查值的包装器,无需添加 InternalsVisibleTo

public class DynamicObjectResultValue : DynamicObject, IEquatable<DynamicObjectResultValue> {
private readonly object value;

public DynamicObjectResultValue(object value) {
this.value = value;
}

#region Operators
public static bool operator ==(DynamicObjectResultValue a, DynamicObjectResultValue b) {
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b)) {
return true;
}
// If one is null, but not both, return false.
if (ReferenceEquals((object)a, null) || ReferenceEquals((object)b, null)) {
return false;
}
// Return true if the fields match:
return a.value == b.value;
}

public static bool operator !=(DynamicObjectResultValue a, DynamicObjectResultValue b) {
return !(a == b);
}
#endregion

public override IEnumerable<string> GetDynamicMemberNames() {
return value.GetType().GetProperties().Select(p => p.Name);
}

public override bool TryGetMember(GetMemberBinder binder, out object result) {
//initialize value
result = null;
//Search possible matches and get its value
var property = value.GetType().GetProperty(binder.Name);
if (property != null) {
// If the property is found,
// set the value parameter and return true.
var propertyValue = property.GetValue(value, null);
result = propertyValue;
return true;
}
// Otherwise, return false.
return false;
}

public override bool Equals(object obj) {
if (obj is DynamicObjectResultValue)
return Equals(obj as DynamicObjectResultValue);
// If parameter is null return false.
if (ReferenceEquals(obj, null)) return false;
// Return true if the fields match:
return this.value == obj;
}

public bool Equals(DynamicObjectResultValue other) {
// If parameter is null return false.
if (ReferenceEquals(other, null)) return false;
// Return true if the fields match:
return this.value == other.value;
}

public override int GetHashCode() {
return ToString().GetHashCode();
}

public override string ToString() {
return string.Format("{0}", value);
}
}

假设有以下 Controller

public class FooController : Controller {

public IActionResult GetAnonymousObject() {

var jsonResult = new {
id = 1,
name = "Foo",
type = "Bar"
};

return Ok(jsonResult);
}

public IActionResult GetAnonymousCollection() {

var jsonResult = Enumerable.Range(1, 20).Select(x => new {
id = x,
name = "Foo" + x,
type = "Bar" + x
}).ToList();

return Ok(jsonResult);
}
}

测试可能看起来像

[TestMethod]
public void TestDynamicResults() {
//Arrange
var controller = new FooController();

//Act
var result = controller.GetAnonymousObject() as OkObjectResult;

//Assert
dynamic obj = new DynamicObjectResultValue(result.Value);

Assert.IsNotNull(obj);
Assert.AreEqual(1, obj.id);
Assert.AreEqual("Foo", obj.name);
Assert.AreEqual(3, obj.name.Length);
Assert.AreEqual("Bar", obj.type);
}

[TestMethod]
public void TestDynamicCollection() {
//Arrange
var controller = new FooController();

//Act
var result = controller.GetAnonymousCollection() as OkObjectResult;

//Assert
Assert.IsNotNull(result, "No ActionResult returned from action method.");
dynamic jsonCollection = result.Value;
foreach (dynamic value in jsonCollection) {
dynamic json = new DynamicObjectResultValue(value);

Assert.IsNotNull(json.id,
"JSON record does not contain \"id\" required property.");
Assert.IsNotNull(json.name,
"JSON record does not contain \"name\" required property.");
Assert.IsNotNull(json.type,
"JSON record does not contain \"type\" required property.");
}
}

关于c# - 如何对返回匿名对象的 ASP.NET Core MVC Controller 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38439811/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com