2017-09-22 15 views
-1

코드를 리팩터링하려고합니다. 이해를 돕기 위해 코드는 actionX에 관한 것입니다.상속을 테스트하는 방법 또는 내 디자인이 잘못 되었나요?

이전 코드는 PENDING 상태에있는 주문에만 작동합니다. 이 상태에서 actionXactiveOrders에 대해 수행됩니다. actionX을 수행하기 전에 fetchA, fetchBfetchC과 같은 작은 단계가 있습니다. 이 코드 조각에는 몇 가지 추가 정보가있는 metaData 개체가 있습니다. 이 metaData을 사용하여 모두 fetch*이 수행됩니다. fetchAfetchB은 서로 의존하지만, fetchC은 다른 것과 독립적이다.

이제 새로운 상태가 도입되었습니다. 그것은 SHIPPED이라고합니다. 이 경우 actionY을 수행해야합니다. 이 상태와 PENDING에있는 유일한 공통 부분은 fetchC입니다.

나에게 이것은 FactoryPattern을 적용하는 완벽한 후보자 인 것으로 보입니다. 그래서 기본 클래스 (fetchC 이래로 인터페이스가 아님)를 만들고 두 아이를 만들었습니다. ActionYHandlerActionXHandler. 공장은 orderType을 입력하고 ActionYHandler 또는 ActionXHandler을 반환합니다.

각 처리기는 특정 동작을 처리하기 위해 handle (MetaData metaData) 메서드가 있습니다. 그러나 fetchC은 수퍼 클래스의 일부로 구현되었습니다 (예 : ActionHandler). 따라서 코드 중복성이 적습니다. 각 처리기는 fetchC이 반환 한 데이터를 사용해야합니다. 따라서 부모 수준에서 fetchC을 구현하면 부모 메서드 만 호출 할 수 있습니다.

Mockito을 사용하여 단위 테스트 케이스를 작성하기 전까지는 모든 것이 완벽하게 작동합니다. 문제는 내가 fetchCactionHandlerXMock 개체를 모의하려고했을 때 발생했습니다. 내가 가지고있는 오류는이 게시물의 하단에 나열되어 있습니다.

오류 종류가 이해가되어서 인터넷 검색이 시작되어 stumbled upon this post이 내 디자인이 잘못되었다고 생각하게되었습니다. 여기에 질문이 있습니다.

  1. fetchC은 (는) 상위 클래스에 속해야합니다. 그렇다면 어떻게 테스트 할 수 있습니까?
  2. 내가 생각할 수있는 다른 옵션은 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) 

답변

1

UnitTests는 행동을 확인합니다.

상속는 (명시 적) 테스트하지 않는 whch 구현 세부입니다.