编写有用的单元测试

3

我有一个简单的页面,其中包含一个网格(Grid),我正在将一个对象集合绑定到该网格上。此外,我还在网格上添加了一些简单的编辑和保存行的功能。我想为这个页面编写单元测试,但是它对我来说并不是很清晰。

例如:

Private Sub LoadGrid()
'Populate Collection
grid.datasource = MyCollection
grid.databind()
end sub

我猜一个Sub真的不需要单元测试,但如果这是一个在网格加载完成时返回true的函数,你该如何编写单元测试呢?对于这样一个简单的网页,还应该进行哪些其他测试呢?
像往常一样,感谢所有提供任何形式意见的人。

3
我猜想子程序确实不需要单元测试。你的猜想是错误的。 - SLaks
+1 - 我对于如何回答你的问题几乎一无所知,因为我不使用或思考单元测试。然而,我也知道我应该考虑它们,大多数项目的开发人员也应该这样做。 - Ryan Kinal
Slaks,一个子程序没有返回任何内容,你如何断言它的正确性? - SIvart Ningvi
通常情况下,如果一个函数没有返回任何东西,那么它就会有副作用或其他可见的状态改变。您可以编写一个测试来验证您的副作用是什么。 - Juliet
2个回答

2
你如何为此编写单元测试?
首先,实际上需要让你的表单可测试。查看这个页面以分离UI和BL层,有大量不同的方法来实现MVC、MVP及其变体,没有一种正确的方法来做到这一点。只要你的代码合理且一致,其他人就能够在你的代码上工作。
我个人发现以下模式适用于大多数UI测试:
- 创建一个表示你的模型的接口。 - 创建一个处理模型所有更新的控制器类。 - 你的视图应该监听模型的更改。
因此,最终你会得到像这样的东西(抱歉,我的VB-fu生疏了,我用C#代替编写):
interface IProductPageModel
{
    int CurrentPage { get; set; }
    int ItemsPerPage { get; set; }
    DataSet ProductDataSet { get; set; }
}

class ProductPageController
{
    public readonly IProductPageModel Model;
    public ProductPageController(IProductPageModel model)
    {
        this.Model = model;
    }

    public void NavigateTo(int page)
    {
        if (page <= 0)
            throw new ArgumentOutOfRangeException("page should be greater than 0");

        Model.CurrentPage = page;
        Model.ProductDataSet = // some call to retrieve next page of data
    }

    // ...
}

这是概念代码,当然,但您可以看到它非常容易进行单元测试。原则上,由于您的控制器不直接依赖于任何特定的视图实现,因此您可以在桌面应用程序、银光等中重复使用相同的控制器代码。
最后,在您的表单端,您可以实现类似于以下的页面:
public class ProductPage : Page, IProductPageModel
{
    ProductPageController controller;

    public ProductPage()
    {
        controller = new ProductPageController(this);
    }

    public DataSet ProductDataSet
    {
        get { return (DataSet)myGrid.DataSource; }
        set { myGrid.DataSource = value; myGrid.DataBind(); }
    }

    protected void NavigateButton_OnCommand(object sender, CommandEventArgs e)
    {
        controller.NavigateTo(Convert.ToInt32(e.CommandArgument));
    }
}

在这里,视图和模型之间没有真正的区别--它们是同一实体。这个想法是尽可能使你的代码后端变得“愚蠢”,以便尽可能多的可测试业务逻辑包含在控制器中。

像这样的简单网页还应该进行什么其他测试?

您需要对任何表单验证进行测试,确保在异常情况下抛出异常,在控制器方法中更新模型的方式符合预期等等。


1

朱丽叶是正确的。

你说的那行代码

'Populate Collection

那是可测试的部分。你可以对集合进行断言,如它是否为空、是否有项目、是否恰好有42个项目。但那将是一个集成测试。

如果能够隔离所有对数据库的调用(返回数据读取器的部分),然后返回一个空的、虚拟的 DbDataReader,那么你就可以测试 UI 和数据库之间的所有内容。

通过启动浏览器并验证表格是否被渲染的测试,同样是依赖于 IIS 正常运行的集成测试(以及一个正常工作的数据库,除非你有一个可以伪造的仓库)。

如果你刚开始,我建议首先寻找所有易于测试的代码,例如那些不依赖数据库的方法,然后再转向那些需要模拟/存根/伪造数据库服务器等更复杂的测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接