Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing - best practice

I use Visual Studio 2010 Professional with MSTest framework to perform unit tests. I have nasty production code to test. First issue is that problematic code is in constructor. I will show examaple :

class ClassToTest
    {
        public SomeEnum UpperBorder;
        public SomeEnum LowerBorder;
        public int var1;
        private readonly SomeEnum2 _ethnicGroup;
        private readonly double _age;
        public int DataStart;
        public int DataEnd;
        public double[] DarkRedDarkYellow;
        public double[] DarkYellowGreen;
        public double[] GreenLightYellow;
        public double[] LightYellowLightRed;

        public ClassToTest(SomeEnum upperBorder, SomeEnum lowerBorder, int var1, SomeEnum2 ethnicGroup, int age)
        {
            UpperBorder = upperBorder;
            LowerBorder = lowerBorder;
            BscanIndex = bscanIndex;
            _ethnicGroup = ethnicGroup;
            _age = age;
            DataStart = 0;
            DataEnd = 0;
            DarkRedDarkYellow = null;
            DarkYellowGreen = null;
            GreenLightYellow = null;
            LightYellowLightRed = null;
        }
}

My question are :

  • write one test with assert statement for each variable? or write couple of tests and in each test check only one variable at once? for example :

 

[TestMethod()]
public void ClassToTest_Constructor_upperBorder_PTest()
{
    //ACT
    var ob = new ClassToTest(SomeEnum.bor1, SomeEnum.bor2,10,SomeEnum2.Asian,10);
    //ASSERT
    Assert.IsNotNull(object);
    Assert.AreEqual(ob.upperBorder,SomeEnum.bor1);
}
  • Should I check if constructor properly assign parameters to private field? Or if there will be property which returns that private field but it performs some another action like triggers event, log action etc.

I cannot find any information about it. So your advice will be most precious.

like image 234
PiterK Avatar asked Jul 21 '11 09:07

PiterK


2 Answers

I would have written one test with many asserts. I know that some people argue against it, but I think that testing one method and validating all relevant postconditions for that method is ok in one test. Otherwise you'll have tons of test methods.

Private fields are normally not tested by unit tests. A unit test should preferrably test externally visible behaviour and state.

I think that a good rule is to strive for as full code coverage as possible for the unit tests. If there is an error in the constructor and the assignments to field, that should be caught in other more high-level tests if they have proper coverage. The only reason I see to write tests for private parts of a class is if it is very hard to trigger certain scenarios, such as error handling routines otherwise. When dealing with threads there can also be reasons to acquire certain private locks before executing a test, to emulate specific scheduling scenarios.

like image 84
Anders Abel Avatar answered Nov 01 '22 16:11

Anders Abel


Write one test with assert statement for each variable gets my vote:

You are testing that the constructor correctly assigns the values given to it.

If you had multiple constructors, with different numbers of parameters, then I'd advocate writing a separate test for each constructor.

If the constructor also sets private fields, then you could also test these - some people don't like checking private members in unit-tests. Indeed, with well-designed code this should not be necessary.

However. personally I often find that, with legacy code that was not designed with Unit Testing in mind, occasionally testing private members can be the easiest way to achieve good test coverage.

Check out this article for an easy way to achieve this.

like image 4
BonyT Avatar answered Nov 01 '22 15:11

BonyT