Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

Visual Studio Fakes 기능에서 Shim... 클래스가 생성되지 않는 경우

다음의 글에서 Fakes 기능을 설명했는데요.

Visual Studio의 단위 테스트 작성 시 Fakes를 이용한 메서드 재정의 방법
; https://www.sysnet.pe.kr/2/0/10858

System(.dll) 참조에 대해 "Add Fakes Assembly"를 했는데도 ShimDateTime 타입이 System.Fakes 네임스페이스 하위에 없는 경우가 발생하기도 합니다. (즉, 정의되어 있지 않은 상황입니다.)

이런 경우는, 다음과 같이 System.4.0.0.0.Fakes 어셈블리만 참조하고 있기 때문입니다.

no_shim_type_1.png

따라서, 그냥 수작업으로 ".\FakesAssemblies" 하위에 있는 mscorlib.4.0.0.0.Fakes.dll 파일을 단위 테스트 프로젝트에 추가해 주면 해결됩니다.



이 외에도, 원하는 타입에 대해 Shim 객체가 생성되어 있지 않을 수도 있습니다. 왜냐하면, Visual Studio는 mscorlib.dll의 경우 극히 일부의 타입만 자동으로 Shim 객체를 생성하기 때문입니다. (가령, System.Fakes 네임스페이스에는 ShimDateTime과 ShimGuid만 제공합니다.)

물론, 원한다면 더 생성하도록 지시할 수 있고 이는 *.fakes 파일을 편집함으로써 가능합니다. 예전에도 이 파일은 다음과 같은 목적으로 편집한 적이 있습니다. ^^

Windows 10에서 Fake 어셈블리를 생성하는 경우 빌드 시 The type or namespace name '...' does not exist in the namespace 컴파일 오류 발생
; https://www.sysnet.pe.kr/2/0/11147

Visual Studio 빌드 오류 - error CS0122: '__ComObject' is inaccessible due to its protection level
; https://www.sysnet.pe.kr/2/0/11039

예를 들어, System.AppDomain 타입에 대해 Shim 객체를 만들고 싶다면 mscorlib.fakes 파일에 다음과 같이 추가할 수 있습니다.

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
  <Assembly Name="mscorlib" Version="4.0.0.0"/>

    <ShimGeneration>
        <Add FullName="System.AppDomain"/>
    </ShimGeneration>
</Fakes>

재미있는 것은, mscorlib.dll이 워낙 기반이 되는 타입이다 보니 모든 클래스에 대해 Shim 타입을 만들 수 있는 것은 아니라는 점입니다. 가령, EventWaitHandle 타입은 Shim 객체 생성이 제공되지 않습니다.

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
  <Assembly Name="mscorlib" Version="4.0.0.0"/>
    <ShimGeneration>
        <Add FullName="System.AppDomain"/>
        <Add FullName="System.Threading.EventWaitHandle" /> <!-- ShimEventWaitHandle 타입이 생성되지 않음 -->
    </ShimGeneration>
</Fakes>

Fakes 기능의 Shim/Stub 타입과 함께 .NET Reflection을 조금 곁들이면 단위 테스트를 넘어 Code Coverage를 거의 100% 가깝게 올리는 것도 가능합니다. (물론, 100% Code Coverage는 들이는 수고에 비하면 효과가 많지는 않으므로 적절한 선에서 끊으시면 됩니다. ^^)




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 2/21/2017]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2023-04-19 12시22분
[김지현] 안녕하세요. 구글로는 답을 찾지 못해 한국말로 단위테스트 fakes라는 키워드를 검색중 이 페이지를 발견했습니다. 도움이 절실한데 도움을 주실 수 있다면 정말 감사하겠습니다. .net core 6로 웹을 만들던중 유닛테스트를 써야하는 상황에서 sql connection 같은 것을 fakes를 이용하여 해결하려합니다. 그런데 제 프로젝트에는 저 references 폴더가 보이지 않고 dependencies만 보이고 dependencies안에는 analyzers, frameworks(이안에 microsoft.NETCore.App이 있고 그안에는 system.core, system.data, system.IO 등 제가 add fakes assembly하고 싶은것들이 들어있습니다), Packages, Projects 들이 있습니다. 만약 제가 frameworks를 클릭하여 들어가서 Add fake assembly를 하면 dependencies 바깥에 fakes라는 일반폴더가 생기고 그안에는 xml로 쓰여진것으로 보이는 <Fakes xmlns ="http:/schemas.microsoft.com/fakes/2011/"> <Assembly Name="System.IO.Compression" Version="6.0.0.0"/></Fakes> 이런 파일이 생깁니다. 제가 이렇게 도움을 요청하는 이유는 단위테스트중에 제가 저런식으로 dependencies안에 있는 dependency하나를 Add Fakes Assembly를 하면 윗줄에서 말한 xml 파일은 fakes폴더안에 자동으로 생성되지만, 장성태님처럼 'System.4.0.0.0.Fakes' 같은것은 생기지않습니다. 사실 파일이 생기건 안생기건 문제는 shim를 사용하여 테스트를 돌리면 테스트가 통과하더라도 퍼센테이지가 올라가지가 않습니다. 그리고 저는 fine code coverage를 사용중인데 거기서도 빨간컬러로 표시가 됩니다. 이것으로 며칠째 시간을 보내고 있습니다. 한국말이 어눌한적 양해부탁드리고 답변해주시면 정말 감사하겠습니다.
[guest]
2023-04-19 01시50분
본문의 내용은 .NET Framework을 예로 든 것이기 때문에 자잘한 차이가 있습니다.

그래도 방법은 같습니다. "단위 테스트" 프로젝트에서 Microsoft.Data.SqlClient에 대해 Fake Assembly를 생성하고 Shim 문맥에서 사용하면 됩니다.

자세한 내용은 퇴근 후 별도의 글로 정리하겠지만, 위의 설명만 잘 파악해도 만드는 데 어렵지 않을 것입니다.
정성태
2023-04-19 02시19분
[김지현] 빠른 답변 정말 감사드립니다. 제가 shim을 사용하여 쓴 테스트는 패스를 했지만, fine code coverage에서는 code가 커버되지못한것으로 뜹니다..
 혹시 fine code coverage가 code coverage를 사용해서 결과를 보여주는지는 모르겠지만, shim을 사용하여 테스트를 해도 본문에 말씀하신거처럼 code coverage 퍼센트가 올라가야 정상입니까..?
[guest]
2023-04-19 09시58분
일단, Fine Code Coverage에서는 Shim 테스트를 할 수 없습니다. 이유는 아래에 밝혔지만,

Visual Studio - Fine Code Coverage에서 동작하지 않는 Fake/Shim 테스트
; https://www.sysnet.pe.kr/2/0/13328

정확한 원인은 알 수 없습니다.
정성태
2023-04-21 12시43분
[김지현] 자세한 답변 정말 감사드립니다. 저의 오류인 건지 원래 가능하지 않은 것인지 혼란스러웠습니다.
[guest]

... 46  47  48  49  50  51  52  53  54  55  56  57  58  59  [60]  ...
NoWriterDateCnt.TitleFile(s)
12116정성태1/15/202010872디버깅 기술: 158. Visual Studio로 디버깅 시 sos.dll 확장 명령어를 (비롯한 windbg의 다양한 기능을) 수행하는 방법
12115정성태1/14/202010599디버깅 기술: 157. C# - PEB.ProcessHeap을 이용해 디버깅 중인지 확인하는 방법파일 다운로드1
12114정성태1/13/202012446디버깅 기술: 156. C# - PDB 파일로부터 심벌(Symbol) 및 타입(Type) 정보 열거 [1]파일 다운로드3
12113정성태1/12/202013093오류 유형: 590. Visual C++ 빌드 오류 - fatal error LNK1104: cannot open file 'atls.lib' [1]
12112정성태1/12/20209711오류 유형: 589. PowerShell - 원격 Invoke-Command 실행 시 "WinRM cannot complete the operation" 오류 발생
12111정성태1/12/202012928디버깅 기술: 155. C# - KernelMemoryIO 드라이버를 이용해 실행 프로그램을 숨기는 방법(DKOM: Direct Kernel Object Modification) [16]파일 다운로드1
12110정성태1/11/202011500디버깅 기술: 154. Patch Guard로 인해 블루 스크린(BSOD)가 발생하는 사례 [5]파일 다운로드1
12109정성태1/10/20209447오류 유형: 588. Driver 프로젝트 빌드 오류 - Inf2Cat error -2: "Inf2Cat, signability test failed."
12108정성태1/10/20209479오류 유형: 587. Kernel Driver 시작 시 127(The specified procedure could not be found.) 오류 메시지 발생
12107정성태1/10/202010395.NET Framework: 877. C# - 프로세스의 모든 핸들을 열람 - 두 번째 이야기
12106정성태1/8/202011813VC++: 136. C++ - OSR Driver Loader와 같은 Legacy 커널 드라이버 설치 프로그램 제작 [1]
12105정성태1/8/202010478디버깅 기술: 153. C# - PEB를 조작해 로드된 DLL을 숨기는 방법
12104정성태1/7/202011177DDK: 9. 커널 메모리를 읽고 쓰는 NT Legacy driver와 C# 클라이언트 프로그램 [4]
12103정성태1/7/202013845DDK: 8. Visual Studio 2019 + WDK Legacy Driver 제작- Hello World 예제 [1]파일 다운로드2
12102정성태1/6/202011507디버깅 기술: 152. User 권한(Ring 3)의 프로그램에서 _ETHREAD 주소(및 커널 메모리를 읽을 수 있다면 _EPROCESS 주소) 구하는 방법
12101정성태1/5/202010907.NET Framework: 876. C# - PEB(Process Environment Block)를 통해 로드된 모듈 목록 열람
12100정성태1/3/20208923.NET Framework: 875. .NET 3.5 이하에서 IntPtr.Add 사용
12099정성태1/3/202011161디버깅 기술: 151. Windows 10 - Process Explorer로 확인한 Handle 정보를 windbg에서 조회 [1]
12098정성태1/2/202010787.NET Framework: 874. C# - 커널 구조체의 Offset 값을 하드 코딩하지 않고 사용하는 방법 [3]
12097정성태1/2/20209376디버깅 기술: 150. windbg - Wow64, x86, x64에서의 커널 구조체(예: TEB) 구조체 확인
12096정성태12/30/201911366디버깅 기술: 149. C# - DbgEng.dll을 이용한 간단한 디버거 제작 [1]
12095정성태12/27/201912654VC++: 135. C++ - string_view의 동작 방식
12094정성태12/26/201910873.NET Framework: 873. C# - 코드를 통해 PDB 심벌 파일 다운로드 방법
12093정성태12/26/201910935.NET Framework: 872. C# - 로딩된 Native DLL의 export 함수 목록 출력파일 다운로드1
12092정성태12/25/201910328디버깅 기술: 148. cdb.exe를 이용해 (ntdll.dll 등에 정의된) 커널 구조체 출력하는 방법
12091정성태12/25/201911825디버깅 기술: 147. pdb 파일을 다운로드하기 위한 symchk.exe 실행에 필요한 최소 파일 [1]
... 46  47  48  49  50  51  52  53  54  55  56  57  58  59  [60]  ...