Когда я использую VS для генерации модульных тестов, я получаю Assert.Inclusive для сгенерированных тестовых методов и обычно я изменяю утверждение, когда я работаю с ними, что-то другое. Я использую вопросительные знаки Assert.Inconclusive в результатах теста в качестве маркеров, чтобы быстро сказать мне, какие тесты я еще не закончил.
Ну, я просто использую это. Из его названия «Неокончательный», я думаю, вы можете использовать, чтобы указать свое недетерминированное состояние, пока вы документируете его значение.
Однако, из описания вашего Average()
метода, я думаю, что, возможно, ваш модульный тест недостаточно атомарен, чтобы охватить только одну «единицу», один конкретный сценарий. Иногда я пишу 2 или 3 метода модульного тестирования для одного метода. Или вы можете разбить свой метод Average()
на более мелкие методы, охватывающие отдельные обязанности. Таким образом, вы можете тестировать эти меньшие методы перед модульным тестированием Average()
one.
Johannes
Так я бы реализовал методы Sum()
и Average()
.
public static class MyMath
{
private static void ValidateInput(ICollection<int> numbers)
{
if (numbers == null)
throw new ArgumentNullException("numbers", "Null input. Nothing to compute!");
if (numbers.Count == 0)
throw new ArgumentException("Input is empty. Nothing to compute!");
}
public static int Sum(int[] numbers)
{
ValidateInput(numbers);
var total = 0;
foreach (var number in numbers)
total += number;
return total;
}
public static double Average(int[] numbers)
{
ValidateInput(numbers);
return Sum(numbers) / numbers.Length;
}
}
Для простоты я просто выкидываю ArgumentException
исключения из метода ValidateInput(ICollection<int>)
. Вы также можете проверить возможность переполнения и выбросить OverflowException
в методе ValidateInput(ICollection<int>)
.
С учетом вышесказанного, вот как я бы протестировал функцию Average(int[])
.
[TestMethod]
public void AverageTest_GoodInput()
{
int[] numbers = {1, 2, 3};
const double expected = 2.0;
var actual = MyMath.Average(numbers);
Assert.AreEqual(expected, actual);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void AverageTest_NullInput()
{
int[] numbers = null;
MyMath.Average(numbers);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void AverageTest_EmptyInput()
{
var numbers = new int[0];
MyMath.Average(numbers);
}
С этими настройками тестов я могу быть уверен, что когда все тесты пройдут, моя функция верна. Ну, кроме случая переполнения. Теперь я могу вернуться к методу ValidateInput(ICollection<int>)
, чтобы добавить логику для проверки переполнения, а затем добавить еще один тест, чтобы ожидать, что OverflowException
будет выброшено для вида входных данных, которые вызывают переполнение. Или делайте это в обратном порядке, если вам нравится подход TDD.
Надеюсь, это поможет прояснить идею.