Java 复杂参数的单元测试

Java 复杂参数的单元测试,java,unit-testing,mocking,easymock,Java,Unit Testing,Mocking,Easymock,假设我有一个方法: someMethod(X anObject) 其中X是一种非常复杂的对象类型。我的意思是,它不是一个可以很容易地在运行中实例化的东西。我需要以某种方式对someMethod进行单元测试,但我不能简单地创建一个X对象作为参数 所以我首先想尝试模拟这个对象,但我遇到的问题是someMethod函数调用了一个对象的许多方法,这意味着这个被模拟的X对象有大量需要调用的函数,因此需要模拟。更糟糕的是,这些被调用的X对象方法返回更多的X对象,这意味着我必须模拟对象,期望模拟方法调用,以

假设我有一个方法:

someMethod(X anObject)
其中X是一种非常复杂的对象类型。我的意思是,它不是一个可以很容易地在运行中实例化的东西。我需要以某种方式对someMethod进行单元测试,但我不能简单地创建一个X对象作为参数

所以我首先想尝试模拟这个对象,但我遇到的问题是someMethod函数调用了一个对象的许多方法,这意味着这个被模拟的X对象有大量需要调用的函数,因此需要模拟。更糟糕的是,这些被调用的X对象方法返回更多的X对象,这意味着我必须模拟对象,期望模拟方法调用,以返回更多的模拟对象

关于这个场景,我有几个问题,因为我对单元测试的概念还不熟悉:

  • 撇开冗长的单元测试方法不谈,我发现我的单元测试不仅是测试一个方法是否有效,而且还指定了实现(因为我基本上是指定方法本身中使用mock函数调用的大部分代码)。这是一个问题吗(主要是单元测试本身的概念)
  • 有没有办法绕过这个问题,哪怕只是让我的单元测试方法变得不那么冗长,更易于维护
  • 我考虑从其他地方获取一个序列化的X对象,保存它,然后每当我调用我的单元测试方法时,我都会取消序列化我的X对象并将其作为参数运行。这只是我脑海中的一些随机想法;有人真的这么做吗

  • 如果有人想知道我到底在做什么,我将使用该接口在java调试器的给定步骤中获取有关stackframe上数据的调试信息。我指的“X”是由接口定义的对象,包括IValue、ivVariable和IStackframe等对象。所有这些变量都是Java调试器在运行时提供给我的。

    您遇到这种困难是设计问题的征兆。当某些东西很难测试时,重构它直到它不难测试


    如果一个对象需要调用另一个对象的太多方法,那么封装性很差,责任也很差。据推测,单一责任原则没有得到遵守。如果代码调用返回对象的方法,并且必须依次调用这些方法,那么就没有遵循德米特定律。

    您的痛苦来自于这样一个事实,即您的方法不符合单一责任原则。你的方法对X做了很多事情——X听起来也太复杂了。这使得测试非常困难——即使是模拟


    将方法分解为可管理的块,每个块只做一件事

    感谢您的回复;让我再解释一下我的目标。我有一个参数X和一个方法parseX(X),它的唯一目的是以某种方式解析X内部的数据以返回。X是复杂的,因此需要很多方法调用,但我的函数只有一个职责。至于德米特定律,IStackFrame对象(X)有IVVariable,其中有IValues,需要调用sendMessage()来返回更多IValues,需要调用toString()来获得表示数据的可用字符串(5行代码)。是否真的需要更多的方法(对于1行程序)?从某种意义上说,您可以在没有它们的情况下使您的测试工作,不需要额外的方法。您可以创建要返回的模拟对象,然后创建返回这些对象的模拟方法。这听起来很难看,很难阅读,也很难维护。为了使代码更易于测试,您可能需要额外的方法。在做出这种改变的过程中,其他有益的改变可能会变得显而易见,这些改变可能涉及到其他方法的分解。