코드를 리팩터링하려고합니다. 이해를 돕기 위해 코드는 actionX
에 관한 것입니다.상속을 테스트하는 방법 또는 내 디자인이 잘못 되었나요?
이전 코드는 PENDING
상태에있는 주문에만 작동합니다. 이 상태에서 actionX
은 activeOrders
에 대해 수행됩니다. actionX
을 수행하기 전에 fetchA
, fetchB
및 fetchC
과 같은 작은 단계가 있습니다. 이 코드 조각에는 몇 가지 추가 정보가있는 metaData
개체가 있습니다. 이 metaData
을 사용하여 모두 fetch*
이 수행됩니다. fetchA
및 fetchB
은 서로 의존하지만, fetchC
은 다른 것과 독립적이다.
이제 새로운 상태가 도입되었습니다. 그것은 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
은 (는) 상위 클래스에 속해야합니다. 그렇다면 어떻게 테스트 할 수 있습니까?- 내가 생각할 수있는 다른 옵션은
factory
레벨에fetchC
메서드를 구현하고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)