2014-10-19 140 views
0

我有一个CountDownTimer类更新控制器更新用户界面。我遇到的问题是当我运行我的单元测试时,我得到一个NllReferenceException,因为事件handlder(Tick)永远不会初始化为空。这个问题最好的解决方案是什么?或者我应该以不同的方式去解决它。谢谢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

你找到的bug在你的代码 - 现在你必须决定什么是预期的行为(除了好看+更新测试,处理空,初始化为某种空的对象,...)和比你还有问题更新问题,所以可以回答。 – 2014-10-19 18:33:40

回答

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; 
    } 
相关问题