有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java模拟框架对我有什么作用?

我听说一些我无法与之交谈的人是jmock的忠实粉丝。我已经做了几年以测试为中心的开发,所以我浏览了网站,看了一些文档,仍然不知道它有什么好处

我对春天也有同样的问题。如果您已经理解了它是什么,那么他们的文档可以很好地解释它,所以我并不认为jmock没有任何价值。我只是不明白这对我有什么好处

因此,如果jmock为我提供了模拟存根数据的能力,那么让我们用一个例子来说明我是如何做的,看看jmock会有什么更好的表现

假设我有一个UI层,上面写着,给我创建一个小部件,小部件服务在创建小部件时,初始化小部件并将其存储在组成小部件所需的三个表中

当我编写测试时,我是这样做的

首先,我将hibernate重新指向我的测试高超音速数据库,这样我就不必进行大量的数据库设置。Hibernate为我创建表

我对类的所有测试都有静态工厂方法,这些方法为我构造类的测试实例。我的每个DAO都创建指向测试模式的测试版本。然后,我的服务类有一个使用测试类生成的DAO构造自己的服务类

现在,当我运行调用该服务的UI控制器的测试时,我正在整个应用程序中测试我的代码。假设在进行单元测试时,这不是通常需要的完全隔离,但在我看来,它为我提供了一个更好的单元测试,因为它在所有支持层中执行真正的代码

由于hibernate下的高超音速飞行速度较慢,所以运行我的所有测试需要稍长的时间,但我的整个构建仍然在旧计算机上运行不到五分钟,以完成完整构建和打包,因此我觉得这是可以接受的

我如何用jmock做不同的事情


共 (2) 个答案

  1. # 1 楼答案

    我没有特别研究JMock(我使用Mockito),但一般来说,模拟框架允许您“模拟”外部服务,这样您一次只需要测试一个类。该类的任何依赖项都可以被模拟,这意味着不进行真正的方法调用,而是调用返回或抛出常量的存根。这是一件好事,因为外部调用可能很慢、不一致或不可靠——这对单元测试来说都是坏事

    为了给出一个如何工作的示例,假设您有一个依赖于web服务客户机的服务类。如果使用真正的web服务客户端进行测试,它可能会关闭,连接可能会变慢,或者web服务背后的数据可能会随着时间的推移而改变。你将如何针对这一点编写可靠的测试?(你不能)。因此,您使用一个模拟框架来模拟/存根web服务客户端,并创建假响应、假错误、假异常来模拟web服务行为。不同之处在于,结果总是快速一致的

    此外,您希望测试给定依赖项可能存在的所有失败案例,但如果不进行模拟,这很难做到。考虑上面给出的例子。如果因为web服务关闭(或超时)而导致web服务抛出IOException,您希望确保代码执行正确的操作,但强制执行该条件并不容易。通过嘲弄,这变得微不足道

  2. # 2 楼答案

    在您的示例中,有两个接口,其中一个将使用模拟框架进行适当的单元测试:

    • UI层和小部件服务之间的接口——用模拟替换小部件服务将允许您单独测试UI层,服务返回手动创建的数据,模拟验证预期的服务调用(以及没有其他调用)是否发生
    • widget服务和DAO之间的接口——通过用mock替换DAO,任何包含复杂逻辑的服务方法都可以单独测试

    Granted that this is not the total isolation generally wanted when doing a unit test, but it provides me, in my opinion, a better unit test because it executes the real code all the way through all of the supporting layers.

    这似乎是你问题的核心。答案有很多方面:

    • 如果您不是孤立地测试组件,那么就没有单元测试,也没有集成测试。正如你所观察到的,这些都很有价值,但它们也有缺点
    • 由于他们同时测试更多的东西,他们往往会更频繁地中断,他们往往会分成大组(当公共功能出现问题时),而当他们这样做时,就更难找出实际问题所在
    • 在你可以测试的场景中,他们更受限制。在集成测试中,很难或不可能模拟某些边缘情况
    • 有时,完全集成测试无法自动化,因为某些组件在您的控制下(例如,第三方Web服务)不足以设置所需的测试数据。在这种情况下,您甚至可能最终在一个高级集成测试中使用模拟框架