Microsoft MVP성태의 닷넷 이야기
VC++: 117. Visual Studio - ATL COM 개체를 단위 테스트 하는 방법 [링크 복사], [링크+제목 복사]
조회: 9374
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

Visual Studio - ATL COM 개체를 단위 테스트 하는 방법

ATL COM DLL의 경우, 직접 COM 객체를 CoCreateInstance로 생성하는 것도 가능하지만 소스 코드를 단위 테스트 프로젝트에 추가하는 방법도 고려해 볼 수 있습니다. (이런 경우, Code Coverage 수치는 안 나옵니다.)

예를 들어, "TestComObject"라는 ATL COM 개체를 만들었다면 다음과 같이 해당 Header 파일을 include하고 소스 코드를 포함시킨 다음, CComObject로 생성할 수 있습니다.

#include "stdafx.h"
#include "CppUnitTest.h"

#include "..\..\dllmain.h"
#include "..\..\TestComObject.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace CppNativeTest
{
    TEST_CLASS(Test_TestComObject)
    {
    public:
        TEST_METHOD(Test_TestComObject_Initialize)
        {
            CComObject<CTestComObject> *inst;
            HRESULT hRes = CComObject<CTestComObject>::CreateInstance(&inst);
        }
    };
}

CComObject를 사용하는 이유는, ATL COM Class의 경우 추상 함수를 포함하고 있기 때문입니다. 그런데, 이렇게 해도 단위 테스트를 실행하면 다음과 같은 오류가 발생합니다.

Test Name:  Test_TestComObject_Initialize
Test FullName:  CppNativeTest::Test_TestComObject::Test_TestComObject_Initialize
Test Source:    d:\unittest\cppnativetest\TestComObjecttest.cpp : line 13
Test Outcome:   Failed
Test Duration:  0:00:00.1421573

Result StackTrace:  
at ATL::CComObject<CTestComObject>::CComObject<CTestComObject>() in c:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\atlcom.h:line 2908
    at ATL::CComObject<CTestComObject>::CreateInstance() in c:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\atlcom.h:line 2966
    at CppNativeTest::Test_TestComObject::Test_TestComObject_Initialize() in d:\unittest\cppnativetest\TestComObjecttest.cpp:line 17
Result Message: Exception Code: C0000005

문제가 발생한 atlcom.h의 소스 코드를 확인해 보면 _pAtlModule 포인터 값이 nullptr임을 알 수 있습니다.

// ===== atlcom.h
// ...[생략]...
template <class Base>
class CComObject : 
    public Base
{
public:
    typedef Base _BaseClass;
    CComObject(_In_opt_ void* = NULL)
    {
        _pAtlModule->Lock();
    }
    // ...[생략]...
}

// ...[생략]...

이 문제를 해결하려면 역시 ATL COM 프로젝트에 있던 Module 클래스를 맞춰주면 됩니다.

#include "..\..\TestComObject\dllmain.h"

TEST_METHOD(Test_TestComObject_Initialize)
{
    CTestComObjectModule _AtlModule;
    _pAtlModule = &_AtlModule;
    CComObject<CTestComObject> *inst;

    HRESULT hRes = CComObject<CTestComObject>::CreateInstance(&inst);
}

이렇게 바꾸고 컴파일하면 이번엔 빌드 오류가 나는데요.

Error LNK2001 unresolved external symbol LIBID_TestComObjectLib

이 값은 [...]_i.c 파일을 단위 테스트 프로젝트에 include 시켜주면 됩니다.

#include "..\..\TestComObject\TestComObject_i.c"



이외에도 단위 테스트 용도의 export 함수들을 ATL DLL에 포함시킨 다음 그것을 통해 COM 클래스를 호출하는 식으로도 고려해 볼 수 있습니다. 이런 경우 Code Coverage까지 모두 계산되어 좋습니다. 대신 출시 버전에 단위 테스트 함수들이 DLL에 포함되어 있는 것은 좋지 않기 때문에 Debug 빌드에만 적용하는 식이어야 할 것입니다.




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







[최초 등록일: ]
[최종 수정일: 4/5/2017]

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

비밀번호

댓글 작성자
 




... 31  32  33  34  [35]  36  37  38  39  40  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
12745정성태7/31/20216621개발 환경 구성: 587. Azure Active Directory - tenant의 관리자 계정 로그인 방법
12744정성태7/30/20217231개발 환경 구성: 586. Azure Active Directory에 연결된 App 목록을 확인하는 방법?
12743정성태7/30/20217919.NET Framework: 1083. Azure Active Directory - 외부 Token Cache 저장소를 사용하는 방법파일 다운로드1
12742정성태7/30/20217219개발 환경 구성: 585. Azure AD 인증을 위한 사용자 인증 유형
12741정성태7/29/20218371.NET Framework: 1082. Azure Active Directory - Microsoft Graph API 호출 방법파일 다운로드1
12740정성태7/29/20217058오류 유형: 747. SharePoint - InvalidOperationException 0x80131509
12739정성태7/28/20217025오류 유형: 746. Azure Active Directory - IDW10106: The 'ClientId' option must be provided.
12738정성태7/28/20217596오류 유형: 745. Azure Active Directory - Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).
12737정성태7/28/20216569오류 유형: 744. Azure Active Directory - The resource principal named api://...[client_id]... was not found in the tenant
12736정성태7/28/20217050오류 유형: 743. Active Azure Directory에서 "API permissions"의 권한 설정이 "Not granted for ..."로 나오는 문제
12735정성태7/27/20217563.NET Framework: 1081. C# - Azure AD 인증을 지원하는 데스크톱 애플리케이션 예제(Windows Forms) [2]파일 다운로드1
12734정성태7/26/202123528스크립트: 20. 특정 단어로 시작하거나/끝나는 문자열을 포함/제외하는 정규 표현식 - Look-around
12733정성태7/23/202110927.NET Framework: 1081. Self-Contained/SingleFile 유형의 .NET Core/5+ 실행 파일을 임베딩한다면? [1]파일 다운로드2
12732정성태7/23/20216228오류 유형: 742. SharePoint - The super user account utilized by the cache is not configured.
12731정성태7/23/20217333개발 환경 구성: 584. Add Internal URLs 화면에서 "Save" 버튼이 비활성화 된 경우
12730정성태7/23/20218871개발 환경 구성: 583. Visual Studio Code - Go 코드에서 입력을 받는 경우
12729정성태7/22/20217858.NET Framework: 1080. xUnit 단위 테스트에 메서드/클래스 수준의 문맥 제공 - Fixture
12728정성태7/22/20217333.NET Framework: 1079. MSTestv2 단위 테스트에 메서드/클래스/어셈블리 수준의 문맥 제공
12727정성태7/21/20218279.NET Framework: 1078. C# 단위 테스트 - MSTestv2/NUnit의 Assert.Inconclusive 사용법(?) [1]
12726정성태7/21/20218103VS.NET IDE: 169. 비주얼 스튜디오 - 단위 테스트 선택 시 MSTestv2 외의 xUnit, NUnit 사용법 [1]
12725정성태7/21/20216880오류 유형: 741. Failed to find the "go" binary in either GOROOT() or PATH
12724정성태7/21/20219525개발 환경 구성: 582. 윈도우 환경에서 Visual Studio Code + Go (Zip) 개발 환경 [1]
12723정성태7/21/20217165오류 유형: 740. SharePoint - Alternate access mappings have not been configured 경고
12722정성태7/20/20217016오류 유형: 739. MSVCR110.dll이 없어 exe 실행이 안 되는 경우
12721정성태7/20/20217640오류 유형: 738. The trust relationship between this workstation and the primary domain failed. - 세 번째 이야기
12720정성태7/19/20216972Linux: 43. .NET Core/5+ 응용 프로그램의 Ubuntu (Debian) 패키지 준비
... 31  32  33  34  [35]  36  37  38  39  40  41  42  43  44  45  ...