网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 论文素材 设计下载 最新论文 下载排行 论文上传 在线投稿 联系我们
返回网学首页
网学联系
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 编程文档 > C/C++ > 正文
测试驱动的C/C++程序开发
来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 12/10/15
下载{$ArticleTitle}原创论文样式
这一点开始运行。

处理数据库

迄今为止,我们只支持销售一种价格为$1.99的商品。让我们加入第四个测试,确保可以处理销售两种商品:

TEST(Sale, sellTwoProducts)
{
Initialize();

char* cookieBarcode = "b234";
int cookiePrice = 50;

BuyItem(milkBarcode);
BuyItem(cookieBarcode);

CHECK(milkPrice + cookiePrice == GetTotal());
}

编译并运行测试,失败了:

Failure: "milkPrice + cookiePrice == GetTotal()" line 46 in SaleTest.cpp

存在一处失败。

让这个测试通过是很简单的:

void BuyItem(char* barCode)
{
if (0 == strcmp(barCode, "a123")) total += 199;
else if (0 == strcmp(barCode, "b234")) total += 50;
}

我们知道必须使用条形码在某个地方进行查找。由于已经通过了测试,我们现在可以重构查找操作,其间需注意始终确保所有测试仍然可以通过。重构是一点一点递增进行的,我们只修改极少量的代码,然后就运行测试以获得反馈。对代码进行剧烈的修改很容易引入缺陷。

现在,我们前进的一小步是以“调用一个GetPrice函数”的形式为查找引入一个占位符。BuyItem中的代码展示了我们希望做的事情。真正的运作细节将于稍晚一会儿给出。

void BuyItem(char* barCode)
{
int price = GetPrice(barCode);
total += price;
}

换句话说,我们的目的在于某个别的函数将会完成根据条形码查找价格的任务。这就是广为人知的目的编程(programming by intention)。这是一个极具威力的技术,它强迫我们工作于愈来愈小的问题,直到“该如何做”显而易见为止。眼下,让我们将条件逻辑从BuyItem移入GetPrice函数:

int GetPrice(char* barCode)
{
if (0 == strcmp(barCode, "a123")) return 199;
else if (0 == strcmp(barCode, "b234")) return 50;
}

我们将这个函数的声明添加进Sale.h并且运行测试以确保它们仍然可以通过。

现在,GetPrice实际上将会到哪里去查找商品的价格呢?当然是到数据库里。

但是,使用一个真正的数据库来进行开发是一件很大的事儿。我们不想“上升”到一个活生生的数据库,因此必须获得一个数据库工作快照(working snapshot)。我们还必须跟踪数据库管理员(DBA)对真正的数据库做出的任何修改,以保持这个快照时新。

关于数据库问题还有一个性能方面的考虑。每一次测试我们都不得不去连接它,而这要占用大量的处理时间,然而我们又需要每隔几分钟就运行测试一次。建立数据库连接的缓慢性将会显著减少我们每天所能完成的工作量。

我们希望“根除”到数据库的调用。BuyItem关心的全部事情只是GetPrice返回商品的价格。它并不关心价格是来自对数据库的查询还是GetPrice当场虚构的一个随机价格。当然了,当使用TDD来构建真正的数据库代码时,我们应该测试真正的GetPrice。

为了使得对GetPrice的调用既能对产品代码的数据库查询有效,又能为我们的测试提供需要的数据,我们必须间接访问它。从一个函数获得不同行为的常见方式是使用函数指针。我们的测试将把指针设置为指向其自己的存根查找函数,而产品代码则将指针指向一个进行实际数据库查询的函数。

在SaleTest中,我们先提供一个存根函数(stub function)GetPriceStub用于查找价格:

int GetPriceStub(char* barCode)
{
if (0 == strcmp(barCode, "a123")) return 199;
else if (0 == strcmp(barCode, "b234")) return 50;
}

我们的测试需要将指向这个存根函数的指针作为参数传递给Initialize。我们将每一个测试中的Initialize修改如下:

Initialize(&GetPriceStub);

这将通不过编译。我们修正Sale.h和Sale.c里的Initialize的原型和定义。它的新签名如下:

void In

  • 上一篇资讯: C++模板元编程
  • 网学推荐

    免费论文

    原创论文

    浏览:
    设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
    版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
    湘ICP备09003080号