对简单集合类进行单元测试 [英] Unit-testing a simple collection class

查看:96
本文介绍了对简单集合类进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下课程:

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);
    }
}

遵循仅测试一件事"的原则,假设我要测试添加"功能. 考虑这种测试的以下可能性:

Following the "only test one thing" principle, suppose I want to test the "Add" function. Consider the following possibility for such a test:

[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()的瘦包装,不应对其本身进行测试,但是如果将来更改为更复杂的东西该怎么办?也许应该始终保留一种简单的"thin wrap"方法来进行测试?

My problem with this solution is that it actually tests 2 methods: Add() and Contains(). Theoretically, there could be a bug in both, that only manifests in scenarios where they are not called one after the other. Of course, Contains() now servers as a thin wrapper for List's Contains() which shouldn't be tested in itself, but what if it changes to something more complex in the future? Perhaps a simple "thin wrap" method should always be kept for testing purposes ?

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

An alternative approach might suggest mocking out or exposing (possibly using InternalsVisibleTo or PrivateObject) the private _list member and have the test inspect it directly, but that could potentially create test maintainability problems if someday the internal list is replaced by some other collection (maybe C5).

是否有更好的方法可以做到这一点? 我对上述实现有何争议?

Is there a better way to do this? Are any of my arguments against the above implementations flawed?

预先感谢, JC

推荐答案

您的测试对我来说似乎完全可以.您可能误解了单元测试的原理.

Your test seems perfectly OK to me. You may have misunderstood a principle of unit testing.

单个测试应该(理想情况下)仅测试一件事情,这是正确的,但这并不意味着它应该只测试一种方法.相反,它应该仅测试一个行为(不变性,遵守某种业务规则等).

A single test should (ideally) only test one thing, that is true, but that does not mean that it should test only one method; rather it should only test one behaviour (an invariant, adherence to a certain business rule, etc.) .

您的测试将测试行为如果添加到新集合中,它将不再为空",这是一个行为:-).

Your test tests the behaviour "if you add to a new set, it is no longer empty", which is a single behaviour :-).

要解决您的其他问题,

  • 从理论上讲,两者都可能存在一个错误,该错误仅在以下情况下才会显现:
    是的,但这仅意味着您需要更多测试:-).例如,将两个数字相加,然后调用包含,或调用不包含加号的包含.

  • Theoretically, there could be a bug in both, that only manifests in scenarios where they are not called one after the other.
    True, but that just means you need more tests :-). For example, add two numbers, then call Contains, or call Contains without Add.

一种替代方法可能建议模拟或暴露(可能使用InternalsVisibleTo)私有_list成员,并让测试直接对其进行检查,但这可能会导致测试的可维护性问题[...]
非常正确,所以不要这样做.单元测试应始终针对被测单元的公共接口.这就是为什么它被称为单元测试,而不是在单元内部混乱"测试的原因;-).

An alternative approach might suggest mocking out or exposing (possibly using InternalsVisibleTo) the private _list member and have the test inspect it directly, but that could potentially create test maintainability problems[...]
Very true, so don't do this. A unit test should always be against the public interface of the unit under test. That's why it's called a unit test, and not a "messing around inside a unit"-test ;-).

这篇关于对简单集合类进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆