gpt4 book ai didi

对简单集合类进行单元测试

转载 作者:行者123 更新时间:2023-12-01 20:21:57 25 4
gpt4 key购买 nike

考虑下面的类:

public class MyIntSet
{
private List<int> _list = new List<int>();

public void Add(int num)
{
if (!_list.Contains(num))
_list.Add(num);
}

public bool Contains(int num)
{
return _list.Contains(num);
}
}

遵循“只测试一件事”的原则,假设我想测试“添加”功能。考虑进行此类测试的以下可能性:

[TestClass]
public class MyIntSetTests
{
[TestMethod]
public void Add_AddOneNumber_SetContainsAddedNumber()
{
MyIntSet set = new MyIntSet();
int num = 0;

set.Add(num);
Assert.IsTrue(set.Contains(num));
}
}

我对这个解决方案的问题是它实际上测试了2 种方法:Add() 和 Contains()。从理论上讲,两者都可能存在错误,该错误仅在未依次调用它们的情况下才会显现。当然,Contains() 现在作为 List 的 Contains() 的薄包装器,本身不应该进行测试,但如果它将来变成更复杂的东西怎么办?也许应该始终保留一个简单的“薄包装”方法用于测试目的?

另一种方法可能建议模拟或公开(可能使用InternalsVisibleTo或PrivateObject)私有(private)_list成员并让测试直接检查它,但是如果有一天内部列表被其他集合替换,这可能会产生测试可维护性问题(也许是C5)。

有更好的方法吗?我反对上述实现的论点是否有缺陷?

提前致谢,JC

最佳答案

我觉得你的测试完全没问题。您可能误解了单元测试的原理。

单个测试应该(理想情况下)只测试一件事,这是事实,但这并不意味着它应该只测试一种方法;相反,它应该只测试一种行为(不变量、遵守特定业务规则等)。

您的测试测试了“如果添加到新集合,它就不再为空”的行为,这是一个单一行为:-)。

解决您的其他问题:

  • 理论上,两者都可能存在错误,该错误仅在未依次调用它们的情况下才会显现。
    确实如此,但这只是意味着您需要更多测试:-)。例如,添加两个数字,然后调用 Contains,或者调用 Contains 而不添加 Add。

  • 另一种方法可能建议模拟或公开(可能使用InternalsVisibleTo)私有(private)_list成员并让测试直接检查它,但这可能会产生测试可维护性问题[...]
    非常正确,所以不要这样做。单元测试应该始终针对被测单元的公共(public)接口(interface)。这就是为什么它被称为单元测试,而不是“单元内部的困惑”-测试;-)。

关于对简单集合类进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1195000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com