programing

익명 유형을 포함하는 JsonResult의 아사트

starjava 2023. 2. 21. 23:20
반응형

익명 유형을 포함하는 JsonResult의 아사트

컨트롤러 중 하나에서 JsonResult를 반환하는 메서드를 유닛 테스트하려고 했습니다.놀랍게도 다음 코드가 작동하지 않았습니다.

[HttpPost]
public JsonResult Test() {
    return Json(new {Id = 123});
}

테스트 방법은 다음과 같습니다(테스트 코드는 다른 어셈블리에 있습니다).

// Act
dynamic jsonResult = testController.Test().Data;

// Assert
Assert.AreEqual(123, jsonResult.Id);

Assert는 예외를 발생시킵니다.

'object'에 'Id'에 대한 정의가 없습니다.

그 후 다음을 사용하여 해결했습니다.

[HttpPost]
public JsonResult Test() {
   dynamic data = new ExpandoObject();
   data.Id = 123;
   return Json(data);
}

왜 첫 번째 것이 작동하지 않는지 이해하려고 노력 중입니다.또한 기본적으로 익명의 유형을 제외한 모든 유형에서 작동하는 것처럼 보입니다.

분명히 하자면 C#다이나믹이 퍼블릭멤버 이외의 멤버에서는 동작하지 않는 것이 문제입니다.이것은 아마도 그런 종류의 일을 막기 위한 의도적인 것이다.LukLed가 말했듯이 익명의 유형은 동일한 어셈블리 내에서만 공개됩니다(정확히 말하면 익명의 유형은 단순히 마킹되어 있습니다).internal,것은 아니다.public)는, 이 장벽에 부딪힙니다.

아마도 가장 깨끗한 솔루션은 다음과 같습니다.InternalsVisibleTo. 공개되지 않은 멤버에 액세스할 수 있는 다른 어셈블리의 이름을 지정할 수 있습니다.테스트에 사용하는 것이 그 존재의 주된 이유 중 하나입니다.이 예에서는 프라이머리 프로젝트의 AssemblyInfo.cs에 다음 행을 입력합니다.

[assembly: InternalsVisibleTo("AssemblyNameOfYourTestProject")]

이렇게 하면 오류가 사라집니다(제가 직접 시도했습니다).

또는 무차별적인 힘의 반사를 사용할 수도 있습니다.

Assert.AreEqual(123, jsonResult.GetType().GetProperty("Id").GetValue(jsonResult, null));

여기서의 답변을 읽고 나서, 한층 더 먼 곳을 찾아본 결과, 또 다른 어프로치의 2009년 msdn 블로그 투고를 발견했습니다.하지만, 코멘트에는, Kieran의 매우 심플하고 우아한 솔루션이 있었습니다..ToString().

원래의 경우:

[HttpPost]
public JsonResult Test()
{
    return Json(new {Id = 123});
}

다음을 수행하여 테스트할 수 있습니다.

var jsonResult = controller.Test();
Assert.AreEqual("{Id = 123}", jsonResult.Data.ToString());

저는 이 솔루션을 매우 선호합니다.

  • 원래 코드를 변경하지 않도록 합니다(InternalsVisibleTo,ExpandoObject),
  • MvcContribRhinoMocks를 사용하지 않도록 합니다(이것들 중 어느 것도 문제 없습니다만, 테스트하기 위해서 추가하는 이유는 무엇입니까).JsonResult?) 및
  • 는 Reflection을 사용하지 않도록 합니다(테스트의 복잡성 추가).

익명 유형은 내부이므로 다른 라이브러리(테스트가 있는 라이브러리)에 노출할 수 없습니다.테스트 코드를 컨트롤러와 같은 라이브러리에 배치하면 동작합니다.

언급URL : https://stackoverflow.com/questions/16876144/asserting-jsonresult-containing-anonymous-type

반응형