如何对通过另一个方法的Action进行单元测试

时间:2015-07-28 10:15:33

标签: c# vb.net unit-testing nunit rhino-mocks

我正在尝试对具有行

的方法进行单元测试
private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{    
      if (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left)
                e.IsInputKey = true;               
}

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{                         
     if (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left)
     {
            // some other treatment [...]
        e.Handled = false;               
     }
}

其中PollingHit是调用类的私有方法,StartPolling的签名是

_pollingService.StartPolling(1000, PollingHit)

现在无论PollingHit()内部是什么,我该如何测试?由于调用此方法的责任在PollingService上,但由于这不是一个被测试的类,我不应该创建它的具体对象。

1 个答案:

答案 0 :(得分:1)

根据该类的所需行为,通过包含_pollingService的类的公共方法对其进行测试。您可以通过检查它调用已传递的操作来测试轮询服务本身,但这并不重要。

当您测试轮询服务时,您应该只测试在开始轮询时它以给定的时间间隔调用给定的操作。轮询服务对PollingHit方法一无所知(因为它在不同的类中)。要对此进行测试,您可以传递pollingservice一个实现计数器的测试方法,并检查计数器是否按预期递增。你可以(而且应该)测试这个而不用 PollingHit方法。

当您来测试使用pollingService的类的行为时,您希望测试其行为,无论其实现方式如何。它使用轮询服务来调用PollingHit方法的事实是一个不相关的实现细节,重要的是当您需要时调用PollingHit方法封装的行为它是。

想象一下,如果有人想出一个推动'通过轮询(这是一个'拉模型)来实现你正在做的事情的基础方式并实现pushNotificationService。使用轮询服务的类的行为应该保持不变,即使您已经重构它以删除pollingService并将其替换为新的pushNotificationService。如果您只测试行为,那么在您进行重构更改后,您的测试将不需要更改。

如果你已经在使用模拟PollingService,那么你可以放弃它并使用你自己的测试双,并使用它来自己控制调用。像这样:

public class TestPollingService : IPollingService 
{ 
    Action theAction; 
    public void StartPolling(double interval, Action action) 
    { 
        theAction = action; 
    } 

    public void TestInvocation() 
    { 
        theAction(); 
    }    
}