1

I'm going to test function returning array of von Neumann neighbours of cell in 2D Array. Cells contains data about simulation.

To conduct test I'm setting new Cell[,] and populate with Cell instances. The test should check if neighbours returned by function is this same instances as expected and in this same order in array.

public class VonNeumanNeighbourhoodTest
{
    private static Cell a,b,c,d,e,f,g,h,i ;    
    private static Cell[,] space;

    public VonNeumanNeighborhoodTest() {
        a = new Cell{ GrainMembership = new Grain(0, Color.Red) };
        b = new Cell{ GrainMembership = new Grain(1, Color.Green) };
        // And so on 
        i = new Cell{ GrainMembership = new Grain(8, Color.Azure) };

        space = new Cell[3, 3]
            {
                { a, b, c },
                { d, e, f },
                { g, h, i }
        };
    }

The problem occures in test method. Cell[] expected always contains {null, null, null, null} in debug instead of eg.{b, f, h, d} reference.

    [Theory]
    [ClassData(typeof(AbsorbingTestData))]
    public void AbsorbingTest(int x, int y, Cell[] expected)
    {
        var neighbours = VonNeumanNeighbourhood.Neighbours(space , x, y, AbsorbingBoundary.BoundaryCondition);
        for(int i = 0; i < 4; i++)
        {
                Assert.Same(neighbours[i], expected[i]);//Checking if neighbours and expected are this same instances
            }
        }

    }
private class AbsorbingTestData : IEnumerable<object[]>
        {   
            public IEnumerator<object[]> GetEnumerator()
            {
                yield return new object[] { 1, 1, new Cell[]{b, f, h, d} }; //e - center
                yield return new object[] { 0, 0, new Cell[]{null, b, d, null} }; //a
                //More cases
            }

            IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
            }

    }

I was trying similar code with [MemberData] attribute but with this same results.

xander
  • 1,689
  • 10
  • 18
chalwa
  • 82
  • 9

1 Answers1

1

I think you're running into an order-of-initialization issue. The Cell instances (private static Cell a,b,c,d,e,f,g,h,i;) are static, but are initialized by an instance constructor. There's no guarantee that the constructor will run before xUnit enumerates the test cases.

Try replacing the instance constructor (public VonNeumanNeighborhoodTest()) with a static initializer (static VonNeumanNeighborhoodTest()). Be careful, though--with a static initializer, the values won't get re-set between tests. You might be better off looking for a way to eliminate the use of static entirely.

xander
  • 1,689
  • 10
  • 18
  • After setting VonNeumanNeighborhoodTest() as static and throwing out constructor it seems to work. In fact cells won't be changed during testing so I don't need to reset them in constructor. I've tried to set the breakpoint in AbsorbingTestData.GetEnumerator() and constructor - only code that was invoked was constructor. – chalwa Nov 14 '19 at 21:37