- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在遗留 C++ 代码库中工作,我想在一个类 DependsOnUgly
上测试一些方法,它具有在大类上不容易破坏的依赖性 (Ugly
) 对文件系统等有很多外部依赖性。我想至少获得一些 DependsOnUgly
被测试的方法,同时尽可能少地修改现有代码。如果不进行大量代码修改,就无法通过工厂方法、方法参数或构造函数参数来创建接缝; Ugly
是一个没有任何抽象基类的直接依赖的具体类,并且有大量方法,很少或没有标记为 virtual
,完全模拟这将是非常乏味的。我没有可用的模拟框架,但我想对 DependsOnUgly
进行测试,以便进行更改。我怎样才能打破 Ugly
的外部依赖关系来对 DependsOnUgly
上的方法进行单元测试?
最佳答案
使用我所说的预处理器模拟——通过预处理器接缝注入(inject)的模拟。
我首先在 this question 中发布了这个概念在 Programmers.SE 上,根据答案我判断这不是一个众所周知的模式,所以我认为我应该分享它。我很难相信以前没有人做过这样的事情,但因为我找不到它的文档,所以我想我会与社区分享它。
为了示例,这里是 Ugly
和 NotAsUgly
的概念性实现。
#ifndef _DEPENDS_ON_UGLY_HPP_
#define _DEPENDS_ON_UGLY_HPP_
#include <string>
#include "Ugly.hpp"
class DependsOnUgly {
public:
std::string getDescription() {
return "Depends on " + Ugly().getName();
}
};
#endif
#ifndef _UGLY_HPP_
#define _UGLY_HPP_
struct Ugly {
double a, b, ..., z;
void extraneousFunction { ... }
std::string getName() { return "Ugly"; }
};
#endif
有两种基本变体。第一个是 DependsOnUgly
只调用 Ugly
的某些方法,而您已经想模拟这些方法。第二个是
DependsOnUgly
使用的所有 Ugly
行为我将此技术称为预处理器部分模拟,因为模拟仅实现被模拟类接口(interface)的必要部分。在 mock 类的头文件中使用与生产类同名的 include guard 来导致生产类永远不会被定义,而是 mock。请务必在 DependsOnUgly.hpp
之前包含模拟。
(请注意,我的测试文件示例不是 self 验证的;这只是为了简单起见,并且与单元测试框架无关。重点是文件顶部的指令,而不是实际的指令测试方法本身。)
#include <iostream>
#include "NotAsUgly.hpp"
#include "DependsOnUgly.hpp"
int main() {
std::cout << DependsOnUgly().getDescription() << std::endl;
}
#ifndef _UGLY_HPP_ // Same name as in Ugly.hpp---deliberately!
#define _UGLY_HPP_
struct Ugly { // Once again, duplicate name is deliberate
std::string getName() { return "not as ugly"; } // All that DependsOnUgly depends on
};
#endif
DependsOnUgly
使用的Ugly
的部分行为我称其为就地子类模拟,因为在这种情况下,Ugly
被子类化,必要的方法被覆盖,而其他方法仍然可用——但是子类的名称仍然是 Ugly
。定义指令用于将 Ugly
重命名为 BaseUgly
;然后使用 undefine 指令,模拟 Ugly
子类 BaseUgly
。请注意,这可能需要根据具体情况将 Ugly
中的某些内容标记为虚拟。
#include <iostream>
#define Ugly BaseUgly
#include "Ugly.hpp"
#undef Ugly
#include "NotAsUgly.hpp"
#include "DependsOnUgly.hpp"
int main() {
std::cout << DependsOnUgly().getDescription() << std::endl;
}
#ifndef _UGLY_HPP_ // Same name as in Ugly.hpp---deliberately!
#define _UGLY_HPP_
struct Ugly: public BaseUgly { // Once again, duplicate name is deliberate
std::string getName() { return "not as ugly"; }
};
#endif
请注意,这两种方法都不太可靠,应谨慎使用。随着更多的代码库正在测试中,它们应该被移走,并在可能的情况下用更标准的方法来打破依赖关系。请注意,如果遗留代码库的 include 指令足够困惑,它们都可能变得无效。但是,我已经成功地将它们用于实际的遗留系统,所以我知道它们可以工作。
关于c++ - 如何在没有模拟框架的情况下对具有讨厌依赖关系的类进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16023539/
我需要开发一个简单的网站,我通常使用 bootstrap CSS 框架,但是我想使用 Gumbyn,它允许我使用 16 列而不是 12 列。 我想知道是否: 我可以轻松地改变绿色吗? 如何使用固定布局
这个问题在这里已经有了答案: 关闭 13 年前。 与直接编写 PHP 代码相比,使用 PHP 框架有哪些优点/缺点?
我开发了一个 Spring/JPA 应用程序:服务、存储库和域层即将完成。 唯一缺少的层是网络层。我正在考虑将 Playframework 2.0 用于 Web 层,但我不确定是否可以在我的 Play
我现有的 struts Web 应用程序具有单点登录功能。然后我将使用 spring 框架创建一个不同的 Web 应用程序。然后想要使用从 struts 应用程序登录的用户来链接新的 spring 应
我首先使用Spark框架和ORMLite处理网页上表单提交的数据,在提交中文字符时看到了unicode问题。我首先想到问题可能是由于ORMLite,因为我的MySQL数据库的字符集已设置为使用utf8
我有一个使用 .Net 4.5 功能的模块,我们的应用程序也适用于 XP 用户。所以我正在考虑将这个 .net 4.5 依赖模块移动到单独的项目中。我怎样才能有一个解决方案,其中有两个项目针对不同的版
我知道这是一个非常笼统的问题,但我想我并不是真的在寻找明确的答案。作为 PHP 框架的新手,我很难理解它。 Javascript 框架,尤其是带有 UI 扩展的框架,似乎通过将 JS 代码与设计分开来
我需要收集一些关于现有 ORM 解决方案的信息。 请随意编写任何编程语言。 你能谈谈你用过的最好的 ORM 框架吗?为什么它比其他的更好? 最佳答案 我使用了 NHibernate 和 Entity
除了 Apple 的 SDK 之外,还有什么强大的 iPhone 框架可供开始开发?有没有可以加快开发时间的方法? 最佳答案 此类框架最大的是Three20 。 Facebook 和许多其他公司都使用
有人可以启发我使用 NodeJS 的 Web 框架吗?我最近开始从免费代码营学习express js,虽然一切进展顺利,但我对express到底是什么感到困惑。是全栈框架吗?纯粹是为了后端吗?我发现您
您可以推荐哪种 Ajax 框架/工具包来构建使用 struts 的 Web 应用程序的 GUI? 最佳答案 我会说你的 AJAX/javascript 库选择应该较少取决于你的后端是如何实现的,而更多
我有生成以下错误的 python 代码: objc[36554]: Class TKApplication is implemented in both /Library/Frameworks/Tk.
首先,很抱歉,如果我问的问题很明显,因为我没有编程背景,那我去吧: 我想运行一系列测试场景并在背景部分声明了几个变量(我打印它们以仔细检查它们是否已正确声明),第一个是整数,另外两个字符串为你可以看到
在我们承担的一个项目中,我们正在寻找一个视频捕获和录制库。我们的基础工作(基于 google 搜索)表明 vlc (libvlc)、ffmpeg (libavcodec) 和 gstreamer 是三
我试过没有运气的情况下寻找某种功能来杀死/中断Play中的正常工作!框架。 我想念什么吗?还是玩了!实际没有添加此功能? 最佳答案 Java stop类中没有像Thread方法那样的东西,由于种种原因
我们希望在我们的系统中保留所有重大事件的记录。例如,在数据库可能存储当前用户状态的地方,事件日志应记录对该状态的所有更改以及更改发生的时间。 事件记录工具应该尽可能接近于事件引发器的零开销,应该容纳结
那里有 ActionScript 2.0/3.0 的测试框架列表吗? 最佳答案 2010-05-18 更新 由于这篇文章有点旧,而且我刚刚收到了赞成票,因此可能值得提供一些更新的信息,这样人们就不会追
我有一个巨大的 numpy 数组列表(一维),它们是不同事件的时间序列。每个点都有一个标签,我想根据其标签对 numpy 数组进行窗口化。我的标签是 0、1 和 2。每个窗口都有一个固定的大小 M。
我是 Play 的新手!并编写了我的第一个应用程序。这个应用程序有一组它依赖的 URL,从 XML 响应中提取数据并返回有效的 URL。 此应用程序需要在不同的环境(Dev、Staging 和 Pro
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我是一名优秀的程序员,十分优秀!