如何对电子邮件客户端进行单元测试

问题描述:

我正在使用桌面电子邮件客户端,我想单元测试我的后端。但是,我看不到一种方法来完成这项工作。为了使我的代码正常工作,它必须连接到正在运行的邮件服务器。除非我将我的单元测试与一个电子邮件帐户绑定,并确保该帐户与我的测试期望的状态相匹配,否则我看不到如何管理这一点。如何对电子邮件客户端进行单元测试

有没有人对如何测试这种应用,它通过设计依赖于外部因素,任何想法?

编辑:

要添加一些细节:我工作的一个C++更高级别的邮件客户端库为我的应用程序,它使用libEtPan,C库,实际处理连接到邮件服务器的详细信息并与之互动。

我要通过测试后承担最后,您指的是实际与电子邮件服务器进行交谈的代码位,并测试此层的其他软件。

现在这可能会或可能不会根据您的定义单位进行集成测试。坦率地说,我不在乎你决定怎样称呼它,但是如果你编写了一些快速运行并且经常执行的自动化测试,那么他们可能会使用与你的单元测试相同的平台。

我想尝试写这个,因此它可以在免得以下两个方面的工作中 - 第一个将它连接到您可以设置和配置,因为你需要一个过程的本地电子邮件服务器。在Java中,我使用Dumpster,但我确定C++存在同样的问题。 第二个将连接到至少一个本地电子邮件服务器,您可以脚本。一个你可以随心所欲地喷洒(所以不是真实的或者在开发者之间共享1),并且运行相同的一组测试。原因是SMTP服务器的开发人员讨厌每个人,你会想检查你的存根工作原理是否与真实情况一样。我认为这相当于One Database Per Developer

现在,如果您还没有编写自己的SMTP客户端,并且围绕现有的第三方API创建了facade,那么我不太可能通过“集成测试”来假设第三方API已经足够受到bug影响脱落。我会嘲笑第三方API并验证门面是否按预期工作。

1)也许你可以在CI周期中这样做,然后在所有开发者之间共享一组电子邮件服务器,本地运行只需使用C++垃圾箱。

+0

你知道一种模拟C API的方法吗?这就是我所看到的问题:如果它是一个C++库,它似乎很简单。另一个考虑是我不能100%确定我应该从第三方API中获得什么,因为这对我来说很新颖,所以我更倾向于设置测试电子邮件服务器而不是嘲笑API的结果。 – 2009-10-08 13:44:57

+0

直到我发布上述内容之前,我才看到这个要求。我并没有做太多的C/C++开发,但http://www.lastcraft.com/cgreen.php看起来很有前途。另一种选择是在它周围创建一个简单的包装器(基本上每个声明的方法都是一个可嘲弄的接口,然后是一个真正的调用)。 – 2009-10-08 14:25:52

+0

但是,如果嘲笑C API是完全不可能的,则存根SMTP服务器如上所述,如果可以的话,使用垃圾箱等)。 – 2009-10-08 14:28:40

我会mock电子邮件服务器,并且嘲笑对象配置为接收/拒收邮件适当(取决于你的测试)。

为了有效地做到这一点,您需要一个接口来与您的电子邮件服务器通信。为了测试,实现是一个嘲弄的对象。对于部署,您可以使用直接与邮件服务器通信的实现来替代它。

见本SO question用于C++嘲笑框架。

+0

问题是,我的后端将被嘲笑是一个C库,所以我不能利用嘲笑它,除非我忽略了一些东西。 – 2009-10-08 13:36:23

+0

快速谷歌指向此:http://www.lastcraft.com/cgreen.php 它可以选择模拟功能。 – 2009-10-08 13:41:23

+0

不要忘记,你可以定义一个新的接口,或者委托给你的库,或者提供模拟的响应。把你的图书馆藏在一个新的界面后面(这可能是一个痛苦,我承认,如果原始图书馆界面很大) – 2009-10-08 13:46:50

正如你最有可能不想考验你使用套接字的,你可能会考虑与虚拟服务器实现,不涉及任何TCP通信取代你的代码的一部分。只需对来自客户端的预期请求进行硬编码,让虚拟服务器作出适当的响应。

你必须找到一种方法与存根来代替真实的东西,那就是完全在你的控制。通常,这是通过模拟框架(例如Rhino.Mocks)完成的。

顺便说一句。:如果你想使用一个“真实”的电子邮件帐户,然后它不是一个单元测试了,但一个集成测试...

Andrew对于嘲笑邮件API是正确的。你在C中的问题可以通过以下两种方式解决。

  • 提供了一个可以被模拟的简单C++包装器。
  • 使用链接器提供C api的测试/模拟版本,您必须使用与库提供的相同的头文件,但是您的单元测试与您的模拟C函数而不是库链接。

有一本很好的书,解决了如何在困难的情况下进行单元测试:“有效地使用遗留代码”,我不能很好地推荐本书。不要被标题拖延,本书将遗留代码视为没有单元测试的任何代码。