Лично я бы рассмотрел , используя один тест для всех параметров. Это не следует обычной догме модульного тестирования, но повышает читаемость тестов (сводя к минимуму объем тестового кода, который посвящен довольно повторяющемуся случаю) и не имеет большого количества недостатков. Да, если тест не пройден, вы не знаете, все ли проверки после первого неудачного теста также не пройдут - но действительно ли это проблема на практике?
Важно убедиться, что у вас есть короткий путь для тестирования кейса. Например, вы можете написать что-то вроде этого (если у вашего фреймворка пока нет этого):
public static void ExpectException<T>(Action action) where T : Exception
{
try
{
action();
Assert.Fail("Expected exception " + typeof(T).Name);
}
catch (T exception)
{
// Expected
}
}
Тогда вы можете написать:
[Test]
public void MyMethodFailsWithInvalidArguments()
{
ExpectException<ArgumentNullException>(() => myClass.MyMethod(null));
ExpectException<ArgumentException>(() => myClass.MyMethod(""));
}
Гораздо лаконичнее, чем выполнение каждого с отдельным блоком try / catch или даже использование атрибута ExpectedException
и нескольких тестов.
Возможно, вы захотите перегрузки для случаев, когда вы также хотите проверить, что в каждом случае не было прикосновений к поддельным объектам (чтобы избежать побочных эффектов), или, возможно, перегрузки для распространенных исключений, таких как ArgumentNullException
.
Для однопараметрических методов вы могли бы даже написать метод для инкапсуляции именно того, что вам нужно:
public void ExpectExceptionForNullAndEmptyStrings(Action<string> action)
{
ExpectException<ArgumentNullException>(() => action(null));
ExpectException<ArgumentException>(() => action(""));
}
затем позвоните с:
[Test]
public void MyMethodFailsWithInvalidArguments()
{
// This *might* work without the
ExpectExceptionForNullAndEmptyStrings(myClass.MyMethod);
}
... и, возможно, еще один для методов с одним параметром, но не возвращаемым типом возврата.
Это, возможно, немного далеко, хотя:)