我想测试以下代码:
foreach (CallQueueData queueData in _configurationProvider.CallQueues.Values)
{
_chimeManager.AddConfig(new ChimeConfigData(
ChimeKey.Create(ChimeType.CallQueue, queueData.Name));
if (queueData.LowChime != null)
{
_chimeManager.AddConfig(new ChimeConfigData(
ChimeKey.Create(ChimeType.QueueLowChime, queueData.Name));
}
if (queueData.HighChime != null)
{
_chimeManager.AddConfig(new ChimeConfigData(
ChimeKey.Create(ChimeType.QueueHighChime, queueData.Name));
}
}
我的一个测试看起来像这样:
public void ShouldAddHighChimeConfigToChimeManager_IfServiceIsStarted_AndHighChimeIsConfigured()
{
// GIVEN
InitializeObjectUnderTestWithougStartingService();
var callQueueData = new CallQueueData
{
Name = "Emergency",
HighChime = new ChimeType(1, "High")
};
CallQueues.Add(callQueueData.Id, callQueueData);
// WHEN
_mgr.Startup();
// THEN
ChimeManager.AssertWasCalled(x => x.AddConfig(Arg<ChimeConfigData>.Matches(
y => y.Key == ChimeKey.Create(ChimeType.HighChime, callQueueData.Name))));
}
这里的问题是ChimeManager的AddConfig方法被多次调用 而且我不想指定在它与我的方法匹配之前必须调用的频率。
// i dont like this repeat twice because this ties the test code to much to the production code
ChimeManager.AssertWasCalled(x => x.AddConfig(Arg<ChimeConfigData>.Matches(
y => y.Key == ChimeKey.Create(ChimeType.HighChime, callQueueData.Name)),
y => y.Repeat.Twice));
我更愿意说:
ChimeManager.AssertWasCalled(x => x.AddConfig(Arg<ChimeConfigData>.Matches(
y => y.Key == ChimeKey.Create(ChimeType.HighChime, callQueueData.Name)),
y => y.Repeat.Any / y.Match.Any));
Unfortunatley Repeat.Any在这种情况下无效,任何没有Match.Any。
我如何断言使用指定的参数调用此方法,但调用它的频率并不重要。当对方法的一个调用与指定的参数匹配时,断言不会失败。
答案 0 :(得分:2)
编写测试以验证方法的结果,而不是编写测试来验证方法的实现(随着时间的推移变得脆弱)。在这种情况下,您似乎希望确保正确填充_chimeManager。
如果您编写的测试只是发送一些数据然后验证结果,那么您的单元测试将不太可能随着时间的推移而中断。假设在将来的某个时刻,_chimeManager的数量通过数据库调用或除了Add方法之外的其他一些方法发生?如果针对实现编写测试,则测试将中断。但是,如果您编写测试以确保在给定某个输入的情况下_chimeManager已正确填充,那么您将获得一个不会因“如何”更改而中断的测试。