在单元测试中使用静态字段会抛出Null引用异常

时间:2015-09-15 12:31:48

标签: c# mstest

[TestClass]
public class SearchTreeTest
{
    static IOiContext iContext;
    static SearchTree searchTree;

    [ClassInitialize]
    public static void InitializeContext(TestContext context)
    {
        //do some stuff here ....
        //initialize searchTree here
    }
    [TestMethod]
    public void SomeMethod_SomeState_SomeExpectation()
    {
        //My test will fail because an error will be thrown here.
        parameters = searchTree.FindParameters(...)
        ...
    }
}

我在单元测试中使用静态字段searchTree,因为我希望所有测试都能访问此字段。我使用ClassInitialize属性在方法中初始化它,以便它应该在我的任何单元测试之前运行。但是,当我在任何测试方法中使用该字段时,它会失败,因为抛出了NullReferenceException。

我是单元测试的新手,也是c#的新手,但我认为这将是一个非常简单的修复。在线搜索时,我找不到任何关于我可能做错的事情。有什么建议吗?

修改

    [TestClass]
    public class SearchTreeTest
    {
        static IXiContext iContext;
        static SearchTree searchTree;

        [ClassInitialize]
        public static void InitializeContext(TestContext context)
        {
            string serverUrl = "http://192.168.3.10:58080/XiServices/ServerDiscovery";
            //private ServiceEndpoint sep;
            IXiEndpointDiscovery iEndpointDiscovery = new XiEndpointDiscovery(serverUrl) as IXiEndpointDiscovery;
            ServiceEndpoint sep = iEndpointDiscovery.GetServiceEndpointsByBinding("IResourceManagement", typeof(NetTcpBinding)).First();

            iContext = XiContext.Initiate(sep, iEndpointDiscovery.ServerEntry,
                    300000, (uint)ContextOptions.EnableJournalDataAccess +
                    (uint)ContextOptions.EnableAlarmsAndEventsAccess + (uint)ContextOptions.EnableDataAccess,
                    (uint)System.Threading.Thread.CurrentThread.CurrentCulture.LCID,
                    Guid.NewGuid().ToString());

            ServiceEndpoint readsep = iEndpointDiscovery.GetServiceEndpointsByBinding("IRead", typeof(NetTcpBinding)).First();
            IXiEndpointBase readEndpoit = iContext.OpenEndpoint(readsep, 30000, new TimeSpan(5000));           

            Node ai = new Node("AI");
            Node ti_101 = new Node("TI-101/AI1/PV.CV");
            Node di_101 = new Node("DI-101/DI1/");
            Node ai_101 = new Node("AI-101/AI1/PV.CV");
            Node aic_30 = new Node("AIC_30");
            Node di_101_pv = new Node("DI-101/DI1/PV_D.CV");
            Node di_101_out = new Node("DI-101/DI1/OUT_D.CV");
            Node aic_301 = new Node("AIC_301/AI1/PV.CV");
            Node aic_302 = new Node("AIC_302/AI/");
            Node aic_302_pv = new Node("AIC_302/AI1/PV.CV");
            Node aic_302_out = new Node("AIC_302/AI1/OUT.CV");

            searchTree = new SearchTree("DA:/../MODULES/", iContext);
            searchTree.Root.Children.Add(ai);
            searchTree.Root.Children.Add(ti_101);
            searchTree.Root.Children.Add(di_101);
            ai.Children.Add(ai_101);
            ai.Children.Add(aic_30);
            aic_30.Children.Add(aic_301);
            aic_30.Children.Add(aic_302);
            aic_302.Children.Add(aic_302_pv);
            aic_302.Children.Add(aic_302_out);
            di_101.Children.Add(di_101_pv);
            di_101.Children.Add(di_101_out);
        }

        [ClassCleanup]
        public static void CleanUpContext()
        {
            iContext.Dispose();
            iContext = null;
        }
        [TestMethod]
        public void staticMethod()
        {
            //I added this just so see what would happen.
            Assert.IsNull(searchTree);
        }

        [TestMethod]
        public void FindParameters_SearchRoot_ReturnsListOfParameter()
        {
            var parameters = searchTree.FindParameters("DA:/../MODULES/");
            var count = parameters.Count;
            var paths = from p in parameters
                    select p.Path;

            var actualPaths = paths.ToList();
            Assert.AreEqual(4, count, count.ToString());
            string[] expectedPaths =  
            {
                "DA:/../MODULES/",
                "DA:/../MODULES/AREA_A",
                "DA:/../MODULES/AREA_1",
                "DA:/../MODULES/BOILER_3"
            };

            foreach (string p in expectedPaths)
            {
                Assert.IsTrue(actualPaths.Contains(p), actualPaths[2]);
            }
        }
    }

修改2

见下图。当我调试我的测试时,当我到达下图中指示的点时它会崩溃。 SearchTree是一个类,它有一个名为Root的属性,类型为Node。 Node有一个名为Children的属性,它是一个List。我之前没有发布这个,因为出于某种原因我无法在调试时从远程机器连接到服务器。

Debug session

解决方案

问题不在于searchTree对象本身。搜索引擎的属性(Children属性)抛出了NullReferenceException。

searchTree = new SearchTree("DA:/../MODULES/", iContext);
searchTree.Root.Children = new List<Node>();
searchTree.Root.Children.Add(ai);
searchTree.Root.Children.Add(ti_101);
searchTree.Root.Children.Add(di_101);
ai.Children = new List<Node>();
ai.Children.Add(ai_101);
ai.Children.Add(aic_30);
aic_30.Children = new List<Node>();
aic_30.Children.Add(aic_301);
aic_30.Children.Add(aic_302);
aic_302.Children = new List<Node>();
aic_302.Children.Add(aic_302_pv);
aic_302.Children.Add(aic_302_out);
di_101.Children = new List<Node>();
di_101.Children.Add(di_101_pv);
di_101.Children.Add(di_101_out);

1 个答案:

答案 0 :(得分:-1)

在使用变量之前,您应该为变量赋值

static SearchTree searchTree = new SearchTree();