2014-10-19 3 views
0

사용자 인터페이스를 업데이트하는 컨트롤러를 업데이트하는 CountDownTimer 클래스가 있습니다. 내가 가진 문제는 handlder (Tick) 이벤트가 절대로 항상 null로 초기화되지 않기 때문에 단위 테스트를 실행할 때 NllReferenceException이 발생합니다. 이 문제에 대한 최선의 해결책은 무엇입니까? 아니면 다르게해야할까요? 감사합니다C# 단위 테스트 대리자 이벤트 처리기

public class CountDownTimer : ICountDownTimer 
{ 
    private int seconds; // Time in seconds 
    private int reSetValue; // Time in seconds 
    private System.Windows.Forms.Timer timer1; 
    public event TickHandler Tick; 
    public EventArgs e = null; 
    public delegate void TickHandler(CountDownTimer m, EventArgs e, int seconds); 

    public CountDownTimer(int seconds) 
    { 
     this.seconds = seconds; 
     reSetValue = seconds; 

     timer1 = new System.Windows.Forms.Timer(); 
     timer1.Tick += new EventHandler(timer1_Tick); // Add Handler(timer1_Tick) 
     timer1.Interval = 1000; // 1 second 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     CallTickHandler(); 

     if (getSeconds() == 0) // Stop Timer at 0 
     { 
      timer1.Stop(); // Stop timer 
     } 
     else 
     { 
      if (getSeconds() % 60 == 0 || getSeconds() >= 1 && getSeconds() <= 10) 
      { 
       CallTickHandler(); 
      } 
     } 
     seconds--; // Decrement seconds 
    } 

    public void StartTimer() 
    { 
     timer1.Start(); 
    } 

    public void StopTimer() 
    { 
     timer1.Stop(); 
    } 

    public void ResetTimer() 
    { 
     timer1.Stop(); 
     seconds = reSetValue; 
     CallTickHandler(); 
    } 

    public void SetTimer(int seconds) 
    { 
     timer1.Stop(); 
     this.seconds = getSeconds(); 
     reSetValue = getSeconds(); 
     CallTickHandler(); 
    } 

    internal void CallTickHandler() 
    { 
     Tick(this, e, getSeconds()); 
    } 

    public Boolean isEnabled() 
    { 
     return timer1.Enabled; 
    } 

    public int getSeconds() 
    { 
     return seconds; 
    } 
} 


public class Controller : ApplicationContext 
{ 
    //Store a reference to the UI 
    internal frmMain MainUI { get; set; } 
    private int seconds = 300; 
    CountDownTimer timer; 

    public Controller() 
    { 
     MainUI = new frmMain(this); 

     //We can do any necessary checks or changes to the MainUI here before it becomes visible 
     MainUI.Show(); 
     timer = new CountDownTimer(seconds); 
     SubscribeToTickListener(timer); 
     TickUpdate(seconds); 
    } 

    internal void TickUpdate(string seconds) 
    { 
     MainUI.lblTimer.Text = ("" + Convert.ToInt32(seconds)/60).PadLeft(2, '0') + "m:" + ("" + Convert.ToInt32(seconds) % 60).PadLeft(2, '0') + "s"; 
    } 

    internal void TickUpdate(int seconds) 
    { 
     MainUI.lblTimer.Text = ("" + seconds/60).PadLeft(2, '0') + "m:" + ("" + seconds % 60).PadLeft(2, '0') + "s"; 
     if (seconds <= 10) 
     { 
      //ss.Speak(seconds.ToString()); 
     } 
     else 
     { 
      //ss.Speak((seconds/60).ToString() + " minute warning"); 
     } 
    } 

    internal void StartTimer() 
    { 
     timer.StartTimer(); 
    } 

    internal void ResetTimer() 
    { 
     timer.ResetTimer(); 
    } 

    internal void StopTimer() 
    { 
     timer.StopTimer(); 
    } 

    internal void SetTimer(int seconds) 
    { 
     timer.SetTimer(seconds); 
    } 

    public void SubscribeToTickListener(CountDownTimer cdt) 
    { 
     cdt.Tick += new CountDownTimer.TickHandler(TickMsgRecieved); 
    } 
    public void TickMsgRecieved(CountDownTimer cdt, EventArgs e, int seconds) 
    { 
     TickUpdate(seconds); 
     TickUpdate(seconds.ToString()); 
    } 
} 


public class CountDownTimerTests 
{ 

    private CountDownTimer t = new CountDownTimer(300); 

    [TestMethod()] 
    public void CountDownTimerTest() 
    { 
     CountDownTimer t = new CountDownTimer(300); 
    } 

    [TestMethod()] 
    public void StartTimerTest() 
    { 
     //CountDownTimer t = new CountDownTimer(300); 
     t.StartTimer(); 
     Boolean expected = t.isEnabled(); 
     Boolean actual = true; 
     Assert.AreEqual(expected, actual); 
    } 

    [TestMethod()] 
    public void StopTimerTest() 
    { 
     //CountDownTimer t = new CountDownTimer(300); 
     t.StartTimer(); 
     t.StopTimer(); 
     Boolean expected = t.isEnabled(); 
     Boolean actual = false; 
     Assert.AreEqual(expected, actual); 
    } 

    [TestMethod()] 
    public void ResetTimerTest() 
    { 
     int expected = t.getSeconds(); 
     t.ResetTimer(); 
     int actual = t.getSeconds(); 
     Assert.AreEqual(expected, actual); 
    } 

    [TestMethod()] 
    public void SetTimerTest() 
    { 
     int expected = t.getSeconds(); 
     t.SetTimer(120); 
     int actual = t.getSeconds(); 
     Assert.AreEqual(expected, actual); 
    } 
} 
+0

코드에서 버그를 발견했습니다. 예상되는 동작 (멋진 예외 + 업데이트 테스트, null 처리, 일종의 null 객체 초기화)을 결정해야합니다. 아직 문제가있는 업데이트 질문이있어 답변을받을 수 있습니다. –

답변

1

이 경우에는 이벤트의 모의 구현을 사용할 수 있습니다. CountDownTimer 클래스의 소비자를 시뮬레이트하기 위해 테스트 클래스에 다음 모의 이벤트를 추가합니다.

[TestInitialize] 
    public void TestSetup() 
    { 
     t.Tick += new CountDownTimer.TickHandler(MockTickEvent); 
    } 
    [TestCleanup] 
    public void TestCleanup() 
    { 
     t.Tick -= MockTickEvent; 
    } 
    void MockTickEvent(CountDownTimer m, EventArgs e, int seconds) 
    { 
     ///you may need to add further test code here to fully cover your code 
     return; 
    }