2014-10-20 2 views
0

Amazon SQS 대기열에서 반송 알림을 생성해야하는 Amazon SES 이메일 전송 기능을 테스트하는 테스트 (NUnit)를 작성했습니다. 대기열에서 반송 알림을 확인하고 새 스레드에서 1 분 동안이 대기열을 루프로 폴링합니다.다중 스레드 단위 테스트 - 잠자기 중지 이벤트를 호출 스레드에 알립니다.

나는 그것을 놓치지 않도록 몇 분의 시간을 늘리고 싶습니다. 그러나 응답이 몇 초 안에 올 수있는 경우 영수증이 확인되면 대기를 계속할 필요가 없으므로 테스트를 완료하는 데 걸리는 시간을 기록하고 싶을 것입니다.

어떻게하면이 스레딩 시나리오를 깨끗한 방법으로 수행 할 수 있으며 테스트 코드로 MethodInMainApp()를 오염시키지 않고도이를 수행 할 수 있습니다. 주요 응용 프로그램에서이 일은 발생하지 않아야합니다 (폴링을 무기한으로 계속 수행해야 함), 테스트 초기에만 중지해야합니다. 아마 두 진입 점 모두에서 ThreadStart 함수를 전달해야하지만 그것은 나에게 묻는 질문에 대한 대답은 아닙니다.

[Test] 
    public async void SendAndLogBounceEmailNotification() 
    { 

     Thread bouncesThread = Startup.MethodInMainApp(); 
     bouncesThread.Start(); 

     bool success = await _emailService.SendAsync(...); 

     Assert.AreEqual(success, true); 

     //Sleep this thread for 1 minute while the 
     //bouncesThread polls for bounce notifications 
     Thread.Sleep(60000); 
    } 


    public static Thread MethodInMainApp() 
    { 
     ... 


     Thread bouncesThread = new Thread(() => 
     { 
      while (true) 
      { 
       ReceiveMessageResponse receiveMessageResponse = sqsBouncesClient.ReceiveMessage(bouncesQueueRequest); 
       if(receiveMessageResponse.Messages.Count > 0) 
       { 
        ProcessQueuedBounce(receiveMessageResponse); 
        //done for test 
       }      
      } 
     }); 

     bouncesThread.SetApartmentState(ApartmentState.STA); 
     return bouncesThread; 
    } 

답변

1

Monitor 클래스를 사용하십시오.

대신 Thread.Sleep(60000)

이를 사용

lock (_lockObject) 
{ 
    Monitor.Wait(_lockObject, 60000); 
} 

을 다음 계속 스레드를 신호 할 위치 : 물론

lock (_lockObject) 
{ 
    Monitor.Pulse(_lockObject); 
} 

이 클래스의 어딘가에 static readonly object _lockObject = new object()를 추가해야합니다.

전반적인 전략이 실제로 올바른 접근이라고 말하는 것은 아닙니다. 단위 테스트 메소드가 응답을 기다리고 검증하는 작업을 수행하는 다른 메소드를 명시 적으로 호출하는 것이 더 좋을 것입니다. 그러나 위의 질문은 귀하의 구체적인 질문을 다루어야합니다.

+0

안녕하세요, 감사합니다.하지만 오류가 발생했습니다. "개체 동기화 메서드가 비동기 코드 블록에서 호출되었습니다." 테스트 클래스에서 lock 객체를 생성하고 선택적 매개 변수로 메서드에 전달합니다. 이 방법은 테스트가 아니며 무시할 때 무시할 수 있습니다 (lockobject! = null). Monitor.Pulse (lockobject); 해당 줄은 오류 – parliament

+0

을 throw합니다. 오류 메시지가 말하는 것처럼 먼저 개체에 대한 잠금을 해제하지 않고 Monitor.Pulse()를 호출하고 있습니다. 선택 사항으로 만들려면 괜찮습니다. 그러나 Monitor.Pulse()를 호출하기 전에 여전히 "lock (lockobject)"이 필요합니다. –