C# 비공개 메서드 테스트 방법/SparkyTestHelpers.NonPublic

개인(또는 내부 또는 보호) 메서드, 속성 및 필드를 어떻게 단위 테스트합니까?

이 질문에 대한 웹 검색을 수행하면 찾을 수 있는 짧은 대답은 DON'T입니다.



일반적으로 비공용 멤버를 사용하는 공용 멤버를 테스트하여 비공용 멤버의 동작을 간접적으로 테스트할 수 있습니다. 단위 테스트에서 비공개 멤버에 액세스하려는 경우 테스트 중인 클래스를 테스트할 수 있도록 리팩터링해야 하는 것은 "코드 냄새"입니다.

...가끔 일시적으로 테스트를 "레거시 코드"로 둘러싸서 리팩토링할 수 있도록 하는 경우도 있습니다. 단위 테스트에서 비공개 멤버에 액세스하는 것은 실용적인 선택입니다. 방법은 다음과 같습니다.

"MSTest"(Microsoft.VisualStudio.TestTools.UnitTesting) 프레임워크를 사용하는 경우 비공개 멤버에 액세스하는 데 사용할 수 있는 도우미PrivateObject가 있습니다.

PrivateObject privateObject = new PrivateObject(subjectUnderTest);

object response = privateObject.Invoke("PrivateMethodName", 3, 
"test", DateTime.Now);


다른 테스트 프레임워크를 사용 중이거나 더 쉬운 구문을 사용하려는 경우(이 작업을 수행하려면 하지 말라고 합니다 🙂) ".NonPublic()"확장 메서드 유창한 구문이 포함되어 있습니다. SparkyTestHelpers.NonPublic NuGet 패키지:

NuGet package | Source code | API documentation



// methods
subjectUnderTest.NonPublic().Method("PrivateMethod").Invoke();
subjectUnderTest.NonPublic().Method("PrivateMethodWithArgs").Invoke(3, "test", DateTime.Now);

object value1 = subjectUnderTest.NonPublic().Method("PrivateFunction").Invoke();
bool typedValue1 = subjectUnderTest.NonPublic().Method("PrivateFunction").Invoke();

object value2 = subjectUnderTest.NonPublic().Method("PrivateFunctionWithArgs").Invoke("test", 3, true);
bool typedValue2 = subjectUnderTest.NonPublic().Method("PrivateFunctionWIthArgs").Invoke("test", 3, true);



// properties
subjectUnderTest.NonPublic().Property("PrivateDateProperty").Set(DateTime.Now);
object value = subjectUnderTest.NonPublic().Property("PrivateDateProperty").Get();
DateTime typedValue = subjectUnderTest.NonPublic().Property("PrivateDateProperty").Get<DateTime>();



// fields:
subjectUnderTest.NonPublic().Field("_stringField").Set("test");
object value = subjectUnderTest.NonPublic().Field("_stringField").Get();
string typedValue = subjectUnderTest.NonPublic().Field("_stringField").Get<string>();


위의 예는 "인스턴스"구성원에 대한 것입니다. 정적 멤버에 액세스하려면 .StaticMethod, .StaticProperty 및 .StaticField를 사용하십시오.

DateTime dt = subjectUnderTest.NonPublic().StaticMethod("PrivateStaticFunction").Invoke<DateTime>("test", 5);
bool boolValue = subjectUnderTest.NonPublic().StaticProperty("StaticProperty").Get<bool>();
string stringValue = subjectUnderTest.NonPublic().StaticField("_staticField").Get<string>();


MsTest의 PrivateObject에는 바인딩 플래그, 형식 배열, CultureInfo 등의 인수가 있는 많은 메서드가 있습니다. 솔직히 언제 필요할지 모르겠지만 위에서 설명한 유창한 구문으로 필요한 작업을 수행할 수 없는 경우 이 패키지의 SparkyTestHelpers.NonPublic.NonPublicMembers 클래스를 사용할 수 있습니다. PrivateObject의 "복제본"이며 동일한 구문을 사용합니다.

좋은 웹페이지 즐겨찾기