我正在尝试重构代码。为了便于理解,代码是关于做actionX
。
旧代码仅适用于PENDING
状态的订单。在此状态下,actionX
已为activeOrders
完成。在执行actionX
之前,有一些小步骤,例如fetchA
,fetchB
和fetchC
。这段代码有一个metaData
对象,它有一些额外的信息。使用此fetch*
执行所有metaData
。 fetchA
和fetchB
相互依赖,fetchC
独立于其他fetches
。
现在,已经引入了新的状态。它被称为SHIPPED
。在这种情况下,需要actionY
。此状态和PENDING
中唯一常见的部分是fetchC
。
对我而言,这似乎是申请FactoryPattern
的完美候选人。所以我创建了一个基类(不是fetchC
常见的接口),并且我创建了两个子节点。 ActionYHandler
和ActionXHandler
。工厂将接收orderType
并返回ActionYHandler
或ActionXHandler
。
每个处理程序都有一个方法handle (MetaData metaData)
来处理它们的特定操作。但是,fetchC
是作为超类的一部分实现的,即ActionHandler
。这样可以减少代码冗余。每个处理程序都需要使用fetchC
返回的数据。因此,通过在父级别实现fetchC
,他们可以只调用其父方法。
在我开始使用Mockito
编写单元测试用例之前,一切都很完美。当我尝试使用fetchC
对象模拟actionHandlerXMock
时出现问题。我得到的错误列在这篇文章的底部。
错误有点意义,所以我开始用谷歌搜索和stumbled upon this post开始让我认为我的设计是错误的。所以这是问题。
fetchC
应该成为父类的一部分。如果是,那么如何进行测试fetchC
级别实施factory
方法,并将从factory.fetchC
检索到的数据传递给handle (MetaData metaData, FetchCResult fetchCResult)
。从测试角度来看,可以轻松地模拟这些数据。但这有点违背了工厂的目的。现在工厂必须了解一些业务逻辑。 错误跟踪
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)
答案 0 :(得分:1)
UnitTests验证行为。
继承是一个实现细节,您不进行测试(显式)。