2008-10-05 6 views
24

많은 내부 기능을 가진 클래스를 단위 테스트하려고합니다. 이것들은 분명히 테스트를 필요로하지만, 테스트 프로젝트는 여러개의 작은 프로젝트를 다루고 있기 때문에 별개입니다. 내가 지금까지있는 것은이는 내부를 표시하지 않습니다 아직 잘 모든 개인 회원을 뱉어하지만System.Reflection을 통해 내부 멤버에 액세스 하시겠습니까?

FieldInfo[] _fields = 
    typeof(ButtonedForm.TitleButton).GetFields(
     BindingFlags.NonPublic | BindingFlags.Instance | 
     BindingFlags.DeclaredOnly); 
Console.WriteLine("{0} fields:", _fields.Length); 
foreach (FieldInfo fi in _fields) 
{ 
    Console.WriteLine(fi.Name); 
} 

. Visual Studio에서 생성 할 수있는 자동 생성 테스트를 사용하면 내부 프로젝트를 Test 프로젝트에 표시하는 것과 관련이 있기 때문에 가능하다고 알고 있습니다. 자, 이제 NUnit을 사용하고 실제로 그것을 좋아하지만, 어떻게하면 같은 것을 얻을 수 있습니까?

답변

32

InternalsVisibleTo 특성을 사용하여 어셈블리의 내부 멤버에 대한 액세스를 유닛 테스트 어셈블리에 부여하는 것이 더 적절합니다.

실제로 귀하의 질문에 ... 내부에 답하고 보호하기 위해 .NET 반사에서 인식되지 않습니다 여기

통해 유용한 추가 정보와 링크를 산책하다 API. 다음은 MSDN의 인용입니다.

C# 키워드는 IL에서 의미가 없으며 Reflection API에서 사용되지 않습니다. IL에서 해당 용어는 가족과 어셈블리입니다. Reflection을 사용하여 내부 메서드를 식별하려면 IsAssembly 속성을 사용합니다. 보호 된 내부 메소드를 식별하려면 IsFamilyOrAssembly을 사용하십시오.

+0

나는 InternalsVisibleTo의 사용에 동의하지만 대답을 주셔서 감사합니다. –

+0

특정 유스 케이스에서 다른 접근 방법이 더 적절할지라도 실제적인 설명이있는 것이 좋습니다. –

+2

참고로 이번 답변에 링크 된 페이지는 내 것이며 내 URL이 변경되었습니다. 그렇기 때문에 404가 표시 될 수 있습니다. http://jason.whitehorn.ws/2007/11/09/The-Wonders-Of-InternalsVisibleTo.aspx –

6

테스트 프로젝트의 어셈블리 이름과 함께 InternalsVisibleTo 어셈블리 수준 특성을 주 프로젝트에 추가하면 내부 멤버가 표시되어야합니다.

[assembly: InternalsVisibleTo("AssemblyB")] 

또는보다 구체적인 타겟팅

:

[assembly:InternalsVisibleTo("AssemblyB, PublicKey=32ab4ba45e0a69a1")] 

참고, 응용 프로그램 어셈블리에 강력한 이름이있는 경우, 테스트

예를 들어 모든 클래스 외부 어셈블리에 다음을 추가 어셈블리도 강하게 명명해야합니다.

6

개인적인 방법에 대한 단위 테스트를 작성해야하는지 물어볼 필요가 있다고 생각합니까? '합리적인'코드 적용 범위를 사용하여 공용 메서드에 대한 단위 테스트를 작성한 경우 결과로 호출해야하는 개인 메서드를 테스트하지 않았습니까?

개인적인 방법으로 테스트를하면 테스트가 더 취약 해집니다. 테스트를 중단하지 않고 모든 개인 메소드의 구현을 변경할 수 있어야합니다.

참고 문헌 :

http://weblogs.asp.net/tgraham/archive/2003/12/31/46984.aspx http://richardsbraindump.blogspot.com/2008/08/should-i-unit-test-private-methods.html http://junit.sourceforge.net/doc/faq/faq.htm#tests_11 http://geekswithblogs.net/geekusconlivus/archive/2006/07/13/85088.aspx

+0

이 작은 함수의 버그가 발생하고 갑자기 10 개의 테스트가 통과하지 않으면 어떻게됩니까? –

+0

내가 생각하는 상황에 따라 다르지만, 예를 들어 제안 된 InternalsVisibleTo를 사용하여 노출시키고 더 많은 타겟 테스트를 작성하는 것이 더 쉽지 않을까요? –

+0

모든 내부 방법을 테스트합니다. 테스트를 거쳐 발생할 수있는 유일한 일은 시간 낭비입니다. –

6

에 코드 만 표시되어 필드 - 필드는 항상 IMO 개인해야 정도로 나는 그것이 내부 구성원을 표시하지 것이다 희망을 것입니다. (잠재적 인 상수를 제외하고.)

ButtonedForm.TitleButton에는 실제로 비공개 필드가 있습니까? 내부 방법을 찾으려면 분명히 GetMethods (또는 GetMembers)으로 전화해야합니다.

다른 사람들이 제안했듯이 InternalsVisibleTo은 테스트하기에 매우 편리합니다. 내부 메소드를 테스트해야하는지 여부에 관해서는 확실히 할 수있는 것이 유용하다는 것을 알게되었습니다. 나는 단위 테스트를 으로 간주하지 않고 블랙 박스 테스트만을 독점합니다. 공용 기능이 간단한 방법으로 연결된 몇 가지 내부 메서드를 사용하여 구현된다는 것을 알게되면 각 내부 메서드와 공용 메서드에 대한 일부 "의사 통합"테스트를 철저히 테스트하는 것이 더 쉽습니다.

+0

맞아, 어쨌든 GetMethods()를 호출해야 했어. 내일 더 많은 표를 얻으려면 +1하십시오. 전 반사 신경에 익숙하지 않니? : D 나는 언젠가 작품에 작은 스크립트 언어를 사용하고 있습니다. –

1

내 상황에서는 InternalsVisible 사용에 대한 정당성이 있습니다. 차트 컨트롤에 소스 코드를 구입합니다. 우리는 소스 컨트롤을 수정하고 우리 자신의 버전을 컴파일해야하는 곳을 발견했습니다. 이제 우리가 아무 것도 깨뜨리지 않았 음을 확인하기 위해 필자가 작성해야하는 단위 테스트가 일부 내부 필드에 대한 액세스 권한이 필요합니다.

이것은 InternalsVisible이 적합한 완벽한 경우입니다.

소스에 액세스 할 수 없다면 어떻게해야할까요? 어떻게 내부 필드에 갈 수 있니? 닷넷 리플렉터는 그 코드를 볼 수는 있지만 일리노이를보고있는 것 같아요.

+0

다른 사람이 언급했듯이 일리노이 내부 구조를 어셈블리라고합니다. System.Reflection을 사용하여 이러한 어셈블리 변수에 액세스 할 수 있습니다. –

관련 문제