VS2017 .Net 표준 라이브러리의 단위 테스트 내부 메소드


150

현재 .Net Standard 1.6 라이브러리를 만들어 최신 Visual Studio 2017 릴리스 후보를 가지고 놀고 있습니다. xUnit을 사용하여 코드를 단위 테스트하고 VS2017에서 여전히 내부 메소드를 테스트 할 수 있는지 궁금합니다.

VS2015의 모든 AssemblyInfo.cs 클래스를 사용하면 지정된 프로젝트에서 내부 메서드를 볼 수 있습니다.

[assembly:InternalsVisibleTo("MyTests")]

VS2017 .Net Standard 프로젝트에 AssemblyInfo.cs 클래스가 없으므로 내부 메소드를 여전히 단위 테스트 할 수 있는지 궁금합니다.


3
외부에서 볼 수있는 기능만으로 코드를 단위 테스트 할 수 있어야 합니다. 결국, 외부 코드의 논리적 경로가 이러한 내부 메소드에 도달 할 수 없다면 처음부터 무엇을하고 있습니까?
David

3
@David 나는 이것을 할 수 있었지만 이미 내부 클래스에 대해 간단한 단위 테스트를 수행했습니다. 테스트에서 더 명확하게 말하면됩니다.
Phil Murray

5
AFAIK에서는이 속성을 namespace블록 외부의 다른 파일에 배치 할 수 있으며 컴파일해야합니다. 에 대한 마술은 없어야합니다 AssemblyInfo.cs. 작동하지 않습니까? 물론 올바른 using절 을 추가 하거나 완전한 속성을 사용해야합니다 [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Something")].
Groo

1
당신이 내부 클래스와 라이브러리를 작성하는 경우 @ 데이비드하고 테스트해야하고 이러한 클래스를 조롱, InternalsVisibleTo예를 들어, 여기 - - 중요 stackoverflow.com/a/17574183/43453
PandaWood

답변:


210

.NET 문서에InternalsVisibleToAttribute 따르면 :

이 속성은 어셈블리 수준에서 적용됩니다. 즉, 소스 코드 파일의 시작 부분에 포함되거나 Visual Studio 프로젝트의 AssemblyInfo 파일에 포함될 수 있습니다.

즉, 임의로 이름이 지정된 .cs 파일에 파일을 배치하면 정상적으로 작동합니다.

// some .cs file included in your project
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("MyTests")]

1
@PhilMurray : 또한 여기에AssemblyInfo.cs 설명 된 것처럼 "클래식" 파일 을 만들 수있는 설정이있는 것 같습니다 . 그렇지 않으면 "설명", "저작권"및 기타 항목과 같은 모든 속성이 .csproj 파일에 저장됩니다.
Groo

43

여기에 설명 된대로 :

https://blog.sanderaernouts.com/make-internals-visible-with-new-csproj-format

다른 ItemGroup을 추가하여 프로젝트 파일 내에 내부 표시 속성을 추가 할 수 있습니다.

<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
        <_Parameter1>$(AssemblyName).Tests</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

또는:

<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
        <_Parameter1>$(MSBuildProjectName).Tests</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

프로젝트 파일이 그러한 관심사를 정의하기에 적합한 장소 인 것 같아서 그 솔루션을 좋아합니다.


8

첫 번째 대답은 완벽하게 괜찮습니다. 여전히 원본에서이 작업을 수행하려는 경우 언제든지 AssemblyInfo파일을 자동 생성하지 않고 수동으로 추가하도록 선택할 수 있습니다.

<PropertyGroup>
   <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

자세한 정보 : https://stackoverflow.com/a/47075759/869033


5

"InternalsVisibleTo"속성은 .Net에 대한 모든 종류의 "화이트 박스"(10 년이라는 용어) 테스트의 핵심입니다. 전면에 "assembly"속성이있는 c # 파일에 배치 할 수 있습니다. MS DOC는 어셈블리 이름이 공개 키 토큰 (서명 된 경우)에 의해 규정되어야한다고 말합니다. 때로는 작동하지 않으며 대신 전체 공개 키를 사용해야합니다. 내부 시스템에 대한 액세스는 동시 시스템 및 기타 여러 상황을 테스트하는 데 중요합니다. https://www.amazon.com/xUnit-Test-Patterns-Refactoring-Code/dp/0131495054를 참조 하십시오 . 이 책에서 Meszaros는 기본적으로 프로그램 개발에 대한 "Design For Test"접근 방식을 구성하는 다양한 코딩 스타일을 설명합니다. 적어도 그것이 내가 수년 동안 그것을 사용한 방식입니다.

추가 : 죄송합니다. 한동안 여기에 없었습니다. 하나의 접근법은 Meszaros에 의해 "테스트 서브 클래스"접근법이라고 불린다. 다시 한 번, "internalsvisableto"를 사용하여 기본 클래스의 내부에 액세스해야합니다. 이것은 훌륭한 솔루션이지만 봉인 클래스에서는 작동하지 않습니다. "Design For Test"를 가르 칠 때, 테스트 가능성을 제공하기 위해 기본 클래스에 "사전 엔지니어링"되어야하는 것들 중 하나라고 제안합니다. 거의 문화적인 것이되어야합니다. 봉인되지 않은 "기본"기본 클래스를 디자인하십시오. 이것을 UnsealedBaseClass 또는 균일하게 인식 할 수있는 것으로 부릅니다. 테스트를 위해 서브 클래 싱 할 클래스입니다. 또한 프로덕션 봉인 클래스를 빌드하기 위해 서브 클래스 화되며, 종종 노출되는 생성자에서만 다릅니다. 나는 원자력 산업에서 일하고 있으며 시험 요건은 매우 심각합니다. 그래서 저는 항상 이런 것들에 대해 생각해야합니다. 그건 그렇고, 프로덕션 코드에 테스트 훅을 남겨 두는 것은 .Net 구현에서 "내부"인 한 우리 분야에서는 문제로 간주되지 않습니다. 테스트하지 않은 결과는 상당히 심오 할 수 있습니다.


1

또 다른 방법은 대상 프로젝트 내에서 테스트해야하는 클래스 (예 : MyFoo)의 공개 메소드 및 결과가없는 '래퍼'TestMyFoo 공개 클래스를 사용하는 것입니다. 이 공용 메소드는 단순히 테스트하려는 기본 클래스를 호출합니다.

대상 프로젝트에 테스트 훅을 제공하면 '이상적이지'않습니다. 그러나 진단 포트가있는 현대의 안정적인 자동차와 JTAG 연결이있는 현대의 신뢰할 수있는 전자 제품을 고려하십시오. 그러나 진단 포트를 사용하여 자동차를 운전할만큼 바보 같은 사람은 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.