Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test with static value

I will try to simplify problem I have with unit tests.

I am testing methods with static private field. If I run test than I must be able predict what is value for static field. This is not problem when I have one test, or if I run tests one by one. Than everything is working fine.

Problem is when I have more than one unit test which change static value and run them all. In case like this only first test will pass and all others will fall.

This is simplified example:

using Xunit;

namespace My.Unit
{
    public class UnitTests
    {
        [Fact]
        public void test1()
        {
            var obj = new TestClass();
            var res = obj.testMethod();

            Assert.Equal(1, res);
        }

        [Fact]
        public void test2()
        {
            var obj = new TestClass();
            var res = obj.testMethod();

            Assert.Equal(1, res);
        }
    }

    public class TestClass
    {
        private static int staticValue = 0;
        public TestClass()
        {
            ++staticValue;
        }

        public int testMethod()
        {
            return staticValue;
        }
    }
}

I would expect from every unit test to have new lifetime for static field, but this is not case.

like image 662
Raskolnikov Avatar asked Oct 17 '17 07:10

Raskolnikov


1 Answers

Depending on the unittest-runner you may or may not have several processes on every test. So in doubt I won´t count on it too much and try to reset the statics on my own.

In your case as the member is a private field you have to use reflection to do this, ideally on setting up every testrun:

[Setup]
public void SetupTest()
{
    var field = typeof(TestClass).GetField("staticValue", BindingFlags.Static | BindingFlags.NonPublic);
    if(field != null)
        field.SetValue(null, 0);
}

As you see initializing valid testcases with statics is quite hacky and cumbersome. There´s no general rule how to circumvent this. Often the static isn´t even needed, sometimes you can introduce some factory that you can mock.

like image 156
MakePeaceGreatAgain Avatar answered Sep 22 '22 12:09

MakePeaceGreatAgain