2010-05-06 74 views
6

这三个测试是相同的,除了它们使用不同的静态函数来创建StartInfo实例。我有这种模式通过我的测试代码,并会喜欢 能够使用[TestCase],或任何其他减少样板代码的方式来简化。据我所知,我不允许使用委托作为[TestCase]的参数,我希望这里的人们对如何使代码更简洁明了有创意。如何简化这些NUNit测试?

[Test] 
    public void ResponseHeadersWorkinPlatform1() 
    { 
     DoResponseHeadersWorkTest(Platform1StartInfo.CreateOneRunning); 
    } 
    [Test] 
    public void ResponseHeadersWorkinPlatform2() 
    { 
     DoResponseHeadersWorkTest(Platform2StartInfo.CreateOneRunning); 
    } 
    [Test] 
    public void ResponseHeadersWorkinPlatform3() 
    { 
     DoResponseHeadersWorkTest(Platform3StartInfo.CreateOneRunning); 
    } 

    void DoResponseHeadersWorkTest(Func<ScriptResource,StartInfo> startInfoCreator) 
    { 
     ScriptResource sr = ScriptResource.Default; 
     var process = startInfoCreator(sr).Start(); 
     //assert some things here 
    } 

回答

8

首先,我不认为原文太糟糕。如果你的断言不同于测试用例和测试用例,那只是一团糟。

无论如何,你可以使用测试用例,但由于使用更复杂的类型,它不能通过标准的[TestCase]属性来完成。相反,您需要使用公共IEnumerable> <>作为数据提供者,然后使用[TestCaseSource]属性标记测试方法。

尝试类似:

public IEnumerable<Func<ScriptResource, StartInfo>> TestCases 
    { 
     get 
     { 
      yield return Platform1StartInfo.CreateOneRunning; 
      yield return Platform2StartInfo.CreateOneRunning; 
      yield return Platform3StartInfo.CreateOneRunning; 
     } 
    } 

    [TestCaseSource("TestCases")] 
    public void MyDataDrivenTest(Func<ScriptResource, StartInfo> startInfoCreator) 
    { 
     ScriptResource sr = ScriptResource.Default; 
     var process = startInfoCreator(sr); 

     // do asserts 
    } 
} 

这是产生含有参数TestCaseData实例的标准图案的更简洁版本。如果您生成TestCaseData的实例,则可以为每个测试添加更多信息和行为(如预期的异常,描述等),但稍微冗长一些。

我真的很喜欢这个东西的部分原因是,你可以为你的“行为”和一种方法为你的“断言”做一个方法,然后独立地混合和匹配它们。例如。我的朋友昨天做了一些事情,他用两个动作来说(“当方法Blah被调用时,ViewModel上的这个方法应该被触发”)。非常简洁有效!

+1

教会了我一个新的概念!加+1 – Prashant 2010-05-07 15:58:40

+0

+1不错。这是一个改进的[NUnit文档链接示例](http://nunit.org/index.php?p=testCaseSource&r=2.5.10)。 – 2011-07-25 18:14:06

0

它看起来不错。你想添加一个工厂吗?或者您可以将这些方法添加到动作列表(在测试设置中),并调用第一个动作委托,第二个动作委托和第三个动作委托。