.NET
래퍼 라이브러리를 만들려고하는 관리되지 않는 DLL
이 있는데 그 대신에 NUnit(v3)
테스트를 실행할 때 다른 동작이 발생합니다 버튼에서 방금 실행하면 WinForm 앱을 클릭하십시오.Unit (Integration) 테스트에서 COM 구성 요소에서 이벤트가 발생하지 않음
배경 : DLL을 시작할 때 DLL을 궁극적으로 TCP 연결로 만드는 원인이되는 Connect()
메서드를 호출합니다. TCP 연결이 설정되면 처리기를 "연결됨"이벤트에 연결하여 알림을받습니다. 일단 연결되면 DLL에서 다른 명령을 호출합니다.
간단한 테스트 Winforms 앱에서 "DLL"을 인스턴스화 한 다음 Connect()
메서드를 호출하는 버튼이 하나 있습니다. 스레드가 완료되면 앱이 약 2 초 동안 유휴 상태가 된 다음 "connected"이벤트 처리기가 예상대로 작동합니다. 이벤트가 아무것도 반환하지 않습니다.
그러나
connect()
는 비용이 많이 드는 작업입니다, 내 라이브러리가 큰 응용 프로그램 향하는 때문에, 나는
AutoResetEvent을 내 라이브러리에
ConnectAsync()
방법을 생성하고
async and await 키워드의 사용을했고, 때문에.
ConnectAsync()
메서드는 TCP 연결이 이벤트에서 발생했다는 알림을 받으면 "인스턴스화 된"DLL의 인스턴스를 반환합니다. 테스트 WinForms 앱에 약간의 리팩터링이 적용되며 예상대로 작동합니다.
다음 단계는 NUnit을 사용하여 통합 테스트를 만드는 것입니다. 그러나 비동기 테스트에서 ConnectAsync()
메서드를 호출하면 원격 응용 프로그램에서 TCP 연결을 설정할 수 있지만 이벤트 처리기는 실행되지 않습니다. 1 일간의 테스트, 검색 및 시행 착오로 인해 ConnectAsync()
은 UnitTest가 아닌 단순한 Winforms 버튼에서 완벽하게 작동합니다. 여기
[Test()]
public async Task Test1()
{
var conn = await GetConnection();
//assert some commands on the conn
}
private async Task<TCPConnector> GetConnection()
{
return await Task.Run(() =>
{
var mre = new AutoResetEvent(false);
var ctrl = new TCPConnector();
ctrl.serverName = server;
ctrl.serverPort = serverPort;
ctrl.onConnected +=() => { mre.Set(); };
ctrl.Connect();
mre.WaitOne();
return ctrl;
});
}
난이 엄격하게 질문 아니라는 것을 알고,하지만 난 난처한 상황에 빠진 시도하는 아이디어를 찾고 있어요. 또는 버튼 클릭 이벤트와 NUnit 테스트 실행간에 다른 점에 대한 포인터. 사용이 작동 MSTEST 경우 경우
이 누군가에게 무언가를 의미한다, 나는 전화 했어 DLL은 관리되지 않는 ActveX에게
갱신 1입니다! 그래서 그것은 NUnit의 시작 환경과 관련이 있습니다.
갱신 2는 : this SO 게시물에 조사를 통해 , 나는 우연히 어떤 단위 테스트 프레임 워크없이 같은 동작을 복제, 대신 등록 무료 COM을 통해. COM이 활성화되고 소비되는 방식과 관련이 있다고 생각하고 있습니까?
해상도 마지막으로 대답을 찾았습니다. this에 대한 그의 대답은 Chris에게 귀속됩니다. 내가해야 할 일을했을 모든 설명 된대로 매니페스트에 <comInterfaceExternalProxyStub />
섹션을 추가하고,
UPDATE 4
마지막 업데이트와 해상도를 무시 빙고이었다.COM, Regfree COM, Interop 및 COM Events의 전 세계를 작업하면서 오도 (misdirection)와 가양 성 (false positives), 내 이해가 부족합니다. 문제는 아직 해결되지 않았습니다.
COM이 단위 테스트의 컨텍스트에서 실행될 때 COM 이벤트가 발생하지 않는다는 것이 중요한 문제입니다. 평범한 .exe에서 실행하면 그들은 정상적으로 작동합니다.
테스트 코드에 대한 자세한 내용을 제공합니다. –
@OrdinaryOrange : 시도해 보겠습니다. [TaskCompletionSource' 사용] (https://msdn.microsoft.com/en-us/library/hh873178(v=vs.110) .aspx # EAP) 대신 'AutoResetEvent'를 사용하여 Task.Run을 실행하십시오. –
스티븐에게 제안 해 주셔서 감사합니다. 제안 된대로 'TaskCompletionSource'를 사용하도록 코드를 리팩토링했지만 이전과 같은 결과를 얻고 있습니다. 나는 그것이 시작 환경 사이의 약간의 차이가되어야한다고 생각하고있다. – OrdinaryOrange