首先,请原谅我使用术语“单位”,或许我的意思是整合测试。但是,在这种情况下,我将DAO方法的测试视为一个单元,而不是试图模拟下划线数据库。
我一直在尝试测试搜索特定实体的特定DAO方法 -
public Factor GetMatchingFactor(int aircraftStoresConfigurationId, int stationId, DateTime timeStamp)
{
// code etc....
}
不,通常情况下,我会尝试进行多次单元测试,可能会对每个参数进行一些测试,以确保每种测试都得到适当的处理。当方法本身处理参数时,我对此通常很满意,更糟糕的是调用依赖项,我可以使用模拟/存根进行测试。然而,在该特定方法中,该方法的结果不是纯函数或一个参数,而是参数和测试数据的函数。
因此,我很难定义像
这样的测试public void TestThatAircraftStoresConfigurationIdParameterIsApplied
public void TestThatStationIdParameterIsApplied
public void TestThatTimeStampParameterIsApplied
由于他们的名字不正确,每个人不只是测试一件事。
这也意味着我正在努力遵循每次测试只有一次断言的规则。
因此,我使用以下代码测试了此方法,覆盖范围相同,可能更有意义。
[Test]
public void TestReturnsCorrectResult()
{
Assert.That(_sut.GetMatchingFactor(10001, Station.Station9Id, new DateTime(2011, 11, 16, 10, 00, 00)).Id, Is.EqualTo(1), "Test 1");
Assert.That(_sut.GetMatchingFactor(10001, Station.Station9Id, new DateTime(2011, 11, 16, 11, 00, 00)).Id, Is.EqualTo(1), "Test 2");
Assert.That(_sut.GetMatchingFactor(10001, Station.Station9Id, new DateTime(2011, 11, 16, 19, 00, 00)).Id, Is.EqualTo(1), "Test 3");
Assert.That(_sut.GetMatchingFactor(10001, Station.Station9Id, new DateTime(2011, 11, 16, 19, 00, 01)).Id, Is.EqualTo(2), "Test 4");
Assert.That(_sut.GetMatchingFactor(10001, Station.Station9Id, new DateTime(2011, 11, 16, 19, 00, 02)).Id, Is.EqualTo(2), "Test 5");
Assert.That(_sut.GetMatchingFactor(10001, Station.Station9Id, new DateTime(2011, 11, 16, 14, 00, 00)).Id, Is.EqualTo(1), "Test 6");
Assert.That(_sut.GetMatchingFactor(10001, Station.Station10Id, new DateTime(2011, 11, 16, 14, 00, 00)).Id, Is.EqualTo(1), "Test 7");
Assert.That(_sut.GetMatchingFactor(10002, Station.Station11Id, new DateTime(2011, 11, 16, 14, 00, 00)).Id, Is.EqualTo(3), "Test 8");
Assert.That(_sut.GetMatchingFactor(10002, Station.Station12Id, new DateTime(2011, 11, 16, 14, 00, 00)).Id, Is.EqualTo(3), "Test 9");
}
我对多个断言感到不舒服,但它似乎是构建这些测试的唯一合理方法。任何人都可以提出更好的选择吗?
答案 0 :(得分:1)
这似乎非常适合NUnit 2.5中的TestCases。您可以按如下方式重写代码:
[TestCase(10001, Station.Station9Id, 2011, 11, 16, 10, 00, 00, 1)]
[TestCase(10001, Station.Station9Id, 2011, 11, 16, 11, 00, 00, 1)]
[TestCase(10001, Station.Station9Id, 2011, 11, 16, 19, 00, 00, 1)]
[TestCase(10001, Station.Station9Id, 2011, 11, 16, 19, 00, 01, 2)]
[TestCase(10001, Station.Station9Id, 2011, 11, 16, 19, 00, 02, 2)]
[TestCase(10001, Station.Station9Id, 2011, 11, 16, 14, 00, 00, 1)]
[TestCase(10001, Station.Station10Id, 2011, 11, 16, 14, 00, 00, 1)]
[TestCase(10002, Station.Station11Id, 2011, 11, 16, 14, 00, 00, 3)]
[TestCase(10002, Station.Station12Id, 2011, 11, 16, 14, 00, 00, 3)]
public void TestReturnsCorrectResult(int configId, int stationId, int yy, int mm, int dd, int h, int m, int s, int expectedResult)
{
Assert.That(_sut.GetMatchingFactor(configId, stationId, new DateTime(yy,mm,dd,h,m,s)).Id, Is.EqualTo(expectedResult));
}
现在只有一个断言,但有很多东西正在测试中。这对于你正在描述的集成测试来说非常好。
请注意,您只能通过TestCase属性传递常量,因此您将无法新建DateTime对象。相反,您必须将年,月,日等作为参数传递给方法,然后自己实例化DateTime。
您可能还会考虑使用某些T4脚本从其他一些数据生成TestCase属性 - 例如CSV文件。我在过去使用过这种方法并取得了相当大的成功,它允许最终用户在Excel中创建测试用例,然后将它们传递给您。