如何在单元测试中设置私有变量

时间:2017-03-03 15:59:40

标签: c# unit-testing asp.net-core nunit

我有一个难度单元测试我的类,其中包含一个对象列表。

这就是我所拥有的

{{1}}

我希望有一个测试证明添加新B不会清除我的列表。但由于列表是私有的,我无法通过我想要测试的代码设置现有列表whitout。由于A类负责创建所有新的B并将它们添加到它的列表中,并且所有新的A应该有一个空的B列表,因此为了测试而在构造函数中添加一个参数感觉很奇怪。

编辑:我修复了GetAllBs,因为它是AddNewBs的复制粘贴错误。

2 个答案:

答案 0 :(得分:4)

首先,这种方法不会编译:

public void GetAllBs(DateTime time)
{
    return _list;
}

它有返回类型void(不返回任何内容)但返回List<B>。此外,您不需要参数来返回结果。将其更改为:

public List<B> GetAllBs()

关于测试:您可以轻松测试您的列表。你的测试方法是这样的:

[TestMethod]
public void Test()
{
    A a = new A();
    a.AddNewB(DateTime.Now);    
    a.AddNewB(DateTime.Now); 

    Assert.AreEqual(2, a.GetAllBs().Count);
}

您应该创建类A的对象并调用AddNewB()来添加一些元素。为了确保在添加新元素后不清除列表,您应该再添加一个列表并检查列表中的Count个元素。为此,您应致电GetAllBs() - 它将返回列表 - 并获取CountCount应该等于2

如果您想确保该方法经过测试,您可以使用一些显示代码覆盖率的工具(DotCoverOpenCover)。

答案 1 :(得分:1)

您还可以使用允许伪造私有字段的单元测试工具,例如我使用具有此功能的Typemock。 所以你可以在测试中创建一个本地列表并将其注入私有字段以测试你的方法:

[TestMethod]
public void TestMethod1()
{
    List<B> fakeList = new List<B> { new B(DateTime.Now), new B(new DateTime(1956, 01, 21)) };
    var classA = Isolate.Fake.Instance<A>(Members.CallOriginal,ConstructorWillBe.Ignored);

    var fakePrivate = Isolate.NonPublic.InstanceField(classA, "_list");
    fakePrivate.Value = fakeList;

    classA.AddNewB(DateTime.MaxValue);

    var res = classA.GetAllBs();

    Assert.AreEqual(3, res.Count);
}