6

我正在使用测试驱动开发方法用 C# 编写一个小游戏。我面临一个问题:

我有一堂课CheckersBoard

public class CheckersBoard
{
    private const string InitialBoardPattern = "B-B-B-B-" +
                                               "-B-B-B-B" +
                                               "B-B-B-B-" +
                                               "--------" +
                                               "--------" +
                                               "-W-W-W-W" +
                                               "W-W-W-W-" +
                                               "-W-W-W-W";

    public SquareStatus[,] Squares { get; private set; }

    public CheckersBoard(IBoardGenerator boardGenerator)
    {
        Squares = boardGenerator.GenerateFromPattern(InitialBoardPattern, 8, 8);
    }

    //....
}

还有一个类BoardGenerator

public class BoardGenerator : IBoardGenerator
{

    public SquareStatus[,] GenerateFromPattern(string pattern, int width, int height)
    {
        //....
    }

}

BoardGenerator允许我以CheckersBoard非常易读的方式进行初始化。所以,我真的很想BoardGenerator在我的单元测试中使用来避免丑陋的数组初始化。

但这违反了我必须保持所有单元测试相互独立的规则。如果测试GenerateFromPattern失败,则会产生“级联”效应,所有使用的测试GenerateFromPattern也会失败。

这是我第一次使用单元测试,所以我有点困惑。我怎样才能避免这个问题?我的设计有问题吗?

4

2 回答 2

2

显然这是一个没有明显答案的常见问题,我碰巧处理了两个类似的问题:

在一定程度上,重用业务逻辑(其他,经过测试的组件)有点类似于在单元测试中使用 3rd 方库——我们假设它们可以工作,并且不费心生成关于它们的额外断言。你会犹豫List<T>在单元测试中使用吗?很可能没有。但是请注意,List<T>许多其他开发人员每天都对其进行测试,并且背后有大型软件公司。你能说同样的话BoardGenerator吗?

另一个需要考虑的问题是,CheckersBoard测试代码对从未工作过的人来说BoardGenerator是否会像对你一样明显?您声称它是可读的,但考虑到创作,这很常见。也许使用数组初始化并不像你想象的那么糟糕(不可读)。

于 2012-09-05T13:34:16.923 回答
1

您可以模拟您的BoardGenerator课程或只是伪造实现,例如

internal class MockBoardGenerator : IBoardGenerator
{
    public SquareStatus[,] GenerateFromPattern(string pattern, int width, int height)
    {
        // return fixed test data
    }
}
于 2012-09-05T12:58:25.850 回答