如何测试继承,或者我的设计是错误的?

时间:2017-09-22 02:47:00

标签: java unit-testing inheritance composition factory-pattern

我正在尝试重构代码。为了便于理解,代码是关于做actionX

旧代码仅适用于PENDING状态的订单。在此状态下,actionX已为activeOrders完成。在执行actionX之前,有一些小步骤,例如fetchAfetchBfetchC。这段代码有一个metaData对象,它有一些额外的信息。使用此fetch*执行所有metaDatafetchAfetchB相互依赖,fetchC独立于其他fetches

现在,已经引入了新的状态。它被称为SHIPPED。在这种情况下,需要actionY。此状态和PENDING中唯一常见的部分是fetchC

对我而言,这似乎是申请FactoryPattern的完美候选人。所以我创建了一个基类(不是fetchC常见的接口),并且我创建了两个子节点。 ActionYHandlerActionXHandler。工厂将接收orderType并返回ActionYHandlerActionXHandler

每个处理程序都有一个方法handle (MetaData metaData)来处理它们的特定操作。但是,fetchC是作为超类的一部分实现的,即ActionHandler。这样可以减少代码冗余。每个处理程序都需要使用fetchC返回的数据。因此,通过在父级别实现fetchC,他们可以只调用其父方法。

在我开始使用Mockito编写单元测试用例之前,一切都很完美。当我尝试使用fetchC对象模拟actionHandlerXMock时出现问题。我得到的错误列在这篇文章的底部。

错误有点意义,所以我开始用谷歌搜索和stumbled upon this post开始让我认为我的设计是错误的。所以这是问题。

  1. fetchC应该成为父类的一部分。如果是,那么如何进行测试
  2. 我能想到的另一个选项是在fetchC级别实施factory方法,并将从factory.fetchC检索到的数据传递给handle (MetaData metaData, FetchCResult fetchCResult)。从测试角度来看,可以轻松地模拟这些数据。但这有点违背了工厂的目的。现在工厂必须了解一些业务逻辑。
  3. 错误跟踪

    org.mockito.exceptions.misusing.MissingMethodInvocationException: 
    when() requires an argument which has to be 'a method call on a mock'.
    For example:
        when(mock.getArticles()).thenReturn(articles);
    
    Also, this error might show up because:
    1. you stub either of: final/private/equals()/hashCode() methods.
       Those methods *cannot* be stubbed/verified.
       Mocking methods declared on non-public parent classes is not supported.
    2. inside when() you don't call method on mock but on some other object.
    at <my_class_name>
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(Unknown Source)
    at org.mockito.runners.MockitoJUnitRunner.run(Unknown Source)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
    

1 个答案:

答案 0 :(得分:1)

UnitTests验证行为

继承是一个实现细节,您不进行测试(显式)。