单元测试Web服务调用

4
我正在开发一个Java项目,该项目分为Web项目和后端项目。 Web通过Web服务调用与后端交互。
Web项目中有一个类负责所有Web服务调用,我想在这个类周围添加测试。我想进行单元测试而不是功能测试,因此我不想必须运行Web服务才能运行测试。如果这个类只是将调用传递到后端,我可能会忽略对其进行测试,但是此时正在进行缓存,因此我想测试它是否正常工作。
当生成jax-ws wsgen Web服务时,它会创建一个接口供前端使用。我已经使用了这个生成的接口来创建一个虚假对象进行测试。这个方法效果还不错,但是这种方法存在问题。
目前,我是唯一一个进行单元测试的人,因此我是唯一一个维护测试代码的人。我希望在构建其他代码时也能构建测试代码,但是如果其他人向其中一个Web服务类中引入新方法,则接口将具有新方法,并且我的虚假对象将无法实现它,因此将无法正常工作。
Web和后端代码项目彼此独立,我不想在它们之间引入依赖关系。因此,在Web服务端点上引入接口似乎不可行,因为如果我将其放在后端,则我的Web代码需要引用它,如果我将其放在前端,则我的后端代码需要引用它。我也无法扩展端点,因为这也会在项目之间引入依赖关系。
我不熟悉Web服务的工作原理以及为Web项目生成类的方式。因此,我不知道如何在后端创建一个可供我在Web项目中使用的接口。
因此,我的问题是,如何在不引入项目依赖关系的情况下使接口对我的前端项目可用?还是有另一种更好的方法可以模拟我调用的后端Web服务?

我认为你需要寻找“模拟”(Mockito,JMockIt)我没有太多使用它们,所以无法给出完整的答案。 - SJuan76
我同意使用Mocking框架的建议。@Beckyreamy - 这实际上比手动模拟简单得多。如果您有一个20个方法的接口,但只想测试一个方法,那么您只需实现该方法即可。此外,这也解决了原始帖子中提到的关于接口添加的问题。如果接口被扩展,模拟框架将为您处理。如果您手动进行模拟,则可能会出现编译错误(除非您记得在其他项目中更新手动模拟)。我已经广泛使用Mockito,它大大简化了我的测试。 - EJK
请查看这个框架:http://code.google.com/p/smock/ - Prasanna Talakanti
EJK和SJuan76 - 感谢你们对模拟框架的反馈。从我目前所了解的情况来看,我还没有被这个想法所吸引。我看到很多评论说使用这些框架的测试容易出现脆弱性;有时测试会失败,有时测试会通过。由于我正在尝试向公司介绍测试,我不希望事情出现偶然性失败,并让人们认为这不值得时间和精力。 - Becky reamy
我过去4年一直使用手写的模拟对象,没有任何问题。如果你正确地使用模拟对象,我们可以在不增加太多额外工作的情况下更换实现方式。手动创建模拟对象所需的时间非常短。这并不意味着我不愿意使用框架。我只是对目前存在的框架所面临的问题感到不舒服。 - Becky reamy
显示剩余4条评论
1个回答

2

首先,我会将缓存代码拆分成一个可测试的单元,不直接依赖于Web服务调用。

至于Web服务,我发现同时具有运行Web服务的功能测试和模拟Web服务的其他测试非常有用。功能测试可以帮助您找到模拟可能遗漏的边界情况。

例如,我正在使用Axis2并从WSDL生成存根。对于模拟,我只需实现或扩展生成的存根。在我们的情况下,真正的Web服务由外部组织实现。通过探索性的功能测试来探测他们的Web服务已经揭示了一些需要处理的异常情况,这些异常情况仅仅通过检查生成的存根是无法发现的。我利用这些信息来更好地模拟这些边界情况。


我很想进去并将缓存提取到一个单独的类集中。这是我计划改进代码的列表之一,然而,由于我是公司的新手,所以在进行此类重大更改时存在一些阻力。 - Becky reamy
关于添加功能测试,我也想这样做。只是我还没有完成这部分。由于我正在向公司介绍整个自动化测试的概念,我试图慢一点,以免混淆单元测试和功能测试的概念。 - Becky reamy
1
我不会请求许可来使代码更具可测试性。这是我的职业责任的一部分。 - Paul Croarkin
1
保罗,我同意改进我正在工作的代码是我的职业责任的一部分。这就是为什么我要向公司引入自动化测试的原因。然而,这个责任的一部分是考虑团队中的其他开发人员。他们不熟悉测试和我想引入的一些模式,所以我不想试图做出很多大的改变,而是试图逐步改进代码。 - Becky reamy

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