Модульное тестирование класса с двойниками - PullRequest
6 голосов
/ 21 апреля 2011

У меня есть класс, который содержит (один или несколько ...) двойников. Например:

public class TestFloatClass{
 public double Double1{get;set;}
 public double Double2{get;set;}

 public void SetDoubleByCalculation(double value){
  Double1 = //Some calculations here;
  Double2 = //Some calculations here;
 } 
}

Я хочу проверить метод SetDoubleByCalculation(double value), поэтому я начинаю писать модульные тесты.

TestFloatClass expected = new TestFloatClass();
expected.Double1 = 100.10;
expected.Double2 = 200.24554;

TestFloatClass actual = new TestFloatClass();
actual.SetDoubleByCalculation(Math.PI); //Just using something random here.

В этом случае expected.Double1 и actual.Double1 примерно одинаковы. Но не совсем из-за точности с плавающей запятой.

Однако я не уверен, как правильно выполнить юнит-тестирование. Это то, что я пробовал до сих пор.

Включение определенной дельты в оператор равенства

Моя первая интуиция сказала, ну, просто включите логику в оператор равенства, как это:

public override bool Equals(object obj){
  return Math.Abs(this.Double1 - obj.Double1) <= 0.00001 &&
              Math.Abs(this.Double1 - obj.Double1)  <= 0.00001; 
}

Но, как сказано в этой теме реализации хэш-кода с двойной точностью , это просто практика.

Просто с помощью переопределения Assert

Я могу продолжить, протестировав его следующим образом:

Assert.Equals(expected.Double1, actual.Double1, 0.0000001); //Or just some precision
Assert.Equals(expected.Double2, acutal.Double2, 0.0000001);

Но опять же, тогда я должен сделать это для КАЖДОГО свойства в этом классе. Если бы TestFloatClass также имел два свойства VeryComplicatedClass vcc & int integer, я бы тоже добавил их.

Assert.Equals(expected.Double1, actual.Double1, 0.0000001); //Or just some precision
Assert.Equals(expected.Double2, actual.Double2, 0.0000001);
Assert.Equals(expected.vcc, actual.vcc);
Assert.Equals(expected.integer, actual.integer);

И оно будет расти, если класс станет больше ...

Итак, мой вопрос

Как лучше всего протестировать этот класс?

Ответы [ 2 ]

3 голосов
/ 21 апреля 2011

Вы должны разделить тесты:

Assert.Equals(expected.Double2, acutal.Double2, 0.0000001);
Assert.Equals(expected.vcc, actual.vcc);

Сделать (отдельные) модульные тесты для свойств Double2 и vcc на классе фактических / ожидаемых.

1 голос
/ 21 апреля 2011

Обратите внимание, что мой ответ на ваш другой вопрос в основном критиковал использование таким образом модифицированного Equals() вместе с GetHashCode() для использования в Hashtable - это просто не сработает, что является хорошим примером, почему это проблематично переопределить Equals() таким образом, что нарушает его контракт. Если вы используете его только для прямых сравнений в тестах, это будет нормально. Но может быть лучше иметь отдельный метод сравнения (возможно, называемый FuzzyEquals()) для использования в тестах, чтобы избежать путаницы.

Кроме того, сравнение с фиксированным эпсилоном проблематично, если ваши значения могут быть очень маленькими или очень большими - для подробностей прочитайте Руководство по плавающей запятой .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...