Юнит-тестирование конструктора - PullRequest
2 голосов
/ 05 января 2012

Я работаю над лабораторной практикой с модульным тестированием, и ниже приведен фрагмент кода из приложения, которое я тестирую. Большинство юнит-тестов закончено, но в отношении конструктора ниже я просто не могу понять, как его протестировать. Например, что именно делает конструктор с элементами массива? Что было бы хорошим способом тестирования строителя?

Может быть, есть добрая душа, которая могла бы дать мне удар в правильном направлении?

  public struct Point { 
    public int x, y;

    public Point(int a, int b) {
      x = a;
      y = b;
    }
  }

...

  public Triangle(Point[] s) {
    sides = new double[s.Length];
    sides[0] = Math.Sqrt(Math.Pow((double)(s[1].x - s[0].x), 2.0) + Math.Pow((double)(s[1].y - s[0].y), 2.0));
    sides[1] = Math.Sqrt(Math.Pow((double)(s[1].x - s[2].x), 2.0) + Math.Pow((double)(s[1].x - s[2].x), 2.0));
    sides[2] = Math.Sqrt(Math.Pow((double)(s[2].x - s[0].x), 2.0) + Math.Pow((double)(s[2].x - s[0].x), 2.0));
  }

...

        [TestMethod()]
        public void TriangleConstructorTest1()
        {
            Point[] s = null; // TODO: Initialize to an appropriate value
            Triangle target = new Triangle(s);
            Assert.Inconclusive("TODO: Implement code to verify target");
        }

Ответы [ 5 ]

4 голосов
/ 05 января 2012

Возможно, я что-то упускаю, но разве это не сработает?

   [TestMethod()]
        public void PointConstructorTest1()
        {
            Point target = new Point(1.5, 2.0);
            Assert.AreEqual(1.5, target.x);
            Assert.AreEqual(2.0, target.y);
        }

Не много смысла в тестировании присваивания переменных, хотя на самом деле ....

3 голосов
/ 05 января 2012

Вы говорите о конструкторе Traingle, не так ли?

Похоже, что он использует теорему Пифагора для вычисления длины сторон треугольника.
Поэтому вы должны проверить, правильно ли выполнены эти вычисления.

Кроме того, вы можете проверить, обнаруживает ли конструктор недопустимые аргументы, например:

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Cannot_Create_Passing_Null()
{
   new Triangle(null);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void Cannot_With_Less_Than_Three_Points()
{
   new Triangle(new[] { new Point(0, 0), new Point(1, 1) });
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void Cannot_Create_With_More_Than_Three_Points()
{
   new Triangle(new[] { new Point(0, 0), new Point(1, 1), new Point(2, 2), new Point(3, 3) });
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void Cannot_Create_With_Two_Identical_Points()
{
   new Triangle(new[] { new Point(0, 0), new Point(0, 0), new Point(1, 1) });
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void Cannot_Create_With_Empty_Array()
{
   new Triangle(new Point[] { });
}
3 голосов
/ 05 января 2012

Трудно ответить из-за некоторых несоответствий в первоначальном вопросе, но я буду опираться на ваш код конструктора, а не на ваш пример теста.

Прежде всего, я бы проверил для массива точек <3 или> 3 соответствующее исключение (которое вы должны проверить и выбросить в своем конструкторе).

Во-первых, я бы дал ваш конструктор, если массив точек будет плохим:

    public Triangle(Point[] s)
    {
        // you could use more specific ArgumentNullException for first,
        // IllegalOperationException for second, etc, you get the point 
        // (no pun intended).
        if (s== null || s.Length != 3 || s.Any(x => x == null)) 
            throw new ArgumentException("s");
        ...
    }

Тогда я бы проверил на нулевую или неправильную длину

    [TestMethod]
    [ExpectedException(typeof(ArgumentException))]
    public void TriangleConstructorWithNullPoints()
    {
        Point[] s = null; 
        Triangle target = new Triangle(s);
    }

[TestMethod]        
[ExpectedException(typeof(ArgumentException))]        
public void TriangleConstructorWithFourPoints()        
{
    Point[] s = new Point[4];
    Triangle target = new Triangle(s);        
}

Тогда я бы проверил общий случай. Возьмите 3/4/5 треугольник, например:

[TestMethod]
public void TriangleConstructorWithFourPoints()
{
    Point[] s = new []
    {
        new Point { x = 0, y = 0 },
        new Point { x = 4, y = 0 },
        new Point { x = 4, y = 3 }
    };

    Triangle target = new Triangle(s);

    Assert.IsTrue(target.Sides.Contains(3.0));
    Assert.IsTrue(target.Sides.Contains(4.0));
    Assert.IsTrue(target.Sides.Contains(5.0));
}

Тогда я бы протестировал любые граничные условия, например, массив длины 3, но одна из точек в массиве равна нулю (проверьте наличие соответствующих исключений) или, если любые две точки совпадают, и т. Д.

1 голос
/ 14 апреля 2013

Я хотел бы начать говорить, что если вы будете следовать рекомендациям из Эрика Липперта , то вы не захотите иметь изменяемые структуры. Теперь, если вы на стороне проверки состояния , что касается модульного тестирования, вы бы пришли к выводу, что нет смысла тестировать неизменяемые объекты, поскольку они могут иметь только одно состояние. В лучшем случае самое лучшее, что вы можете достичь, это проверить, что конструктор не сделал что-то вроде this.x = b.

1 голос
/ 05 января 2012

Я предполагаю, что у вас есть свойство Sides, вы можете утверждать, что значения, возвращаемые из этого, должны быть такими, какими они должны быть.

Вы также можете немного реорганизовать свой код, так как мне кажется, что эти 3 строки почти идентичны, но с разными Point параметрами.

Кроме того, вставленный вами конструктор отличается от конструктора в вашем тестовом примере.

...