Unit-testing of a constructor

老子叫甜甜 提交于 2021-02-08 04:41:01

问题


I'm working on a laboratory practical with unit-testing, and below is a piece of code from the application that i'm testing. Most of the unit-testings are finished, but regarding the constructor below I just can't figure out how to test it. For example, what exactly is the constructor doing with the array elements? What would be a good way of testing the construtor?

Is there maybe a kind soul out there who could give me a kick in the right direction?

  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");
        }

回答1:


You are talking about the Traingle-constructor, aren't you?

It looks like it is using the Pythagorean theorem to calculate the length of the triangle sides.
So you should test whether this calculation is done correctly.

In addition, you could check if the constructor detects invalid arguments, e.g.:

[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[] { });
}



回答2:


Perhaps I'm missing something but won't this do it?

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

Not much point in testing variable assigning though really....




回答3:


Hard to answer based on some inconsistencies in the initial question, but I'll go based on your constructor code and not your sample test.

First of all, I'd test for an array of point < 3 or > 3 an appropriate exception is thrown (which you should check and throw in your constructor).

First, I'd have your constructor throw if the array of points is bad:

    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");
        ...
    }

Then, I'd test for the null or non-correct length

    [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);        
}

Then I'd test for the common case. Take a 3/4/5 triangle for instance:      

[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));
}

Then I'd test any edge conditions, like an array of length 3, but one of the points in the array is null, (check for appropriate exception) or if any two points are the same, so on.




回答4:


I am assuming you have a Sides property, you could assert that the values returned from this are what they should be.

You may also want to refactor your code a bit, as to me it looks like those 3 lines are near identical, but with different Point parameters.

Also, the constructor you pasted isn't the same as the constructor in your example test.




回答5:


I would like to start saying that if you follow the recommendations of Eric Lippert, then you don't want to have mutable structs. Now, if you're on the side of state verification as Unit Testing concerns, you would conclude that there's no point in testing immutable objects as they can only have one state. Best case, the most you can achieve is testing that the constructor did not do something like this.x = b.



来源:https://stackoverflow.com/questions/8746762/unit-testing-of-a-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!