2016-08-16 4 views
2

외부 API 호출을 모의하려고하지만 코드 구조로 mockito가 도움이되는지 여부를 알 수 없습니다. 내가 외부 서비스에 대한 호출입니다 postCall을 조롱 할 필요가 그래서 지금mockito를 사용하여 기본 클래스의 메소드를 모의하거나 정적 메소드를 모의합니다

public class SimpleController extends Anothercontroller 
{ 
    @RequestMapping("/classA") 
    { 
    ....... 
    String response = postCall(url, .....); 
    } 
} 

public class AnotherController 
{ 
    public String postCall (String url, ......) 
    { 
    //This is the apache library to make post calls 
    return WebUtil.post(......); 
    } 
} 

:

은 내가 SimpleController 있습니다.

여기에 내가이 곳에서 조롱 수 있습니다

1) postCall()는 SimpleController에서, howevere 나는 그것이 구성을 통해 상속을 선호하기 때문에 그렇게하는 방법을 잘 모릅니다.

2) WebUtil.post (.....) 그러나 mockito가 정적 메서드를 모의 할 수있는 방법을 모르겠습니다.

코드 구조를 리팩터링하고 싶지 않습니다. 다른 코드도 많이 사용하고 있기 때문입니다.

답변

1

1) SimpleController에서 postCall(), howevere 내가 을 수행하는 방법을 잘 모릅니다이 구성을 통해 상속을 선호하기 때문에 그.

스파이를 사용하는 Mockito에서 가능합니다. 스파이는 다른 방법으로 지정하지 않는 한 실제 방법을 사용하는 객체의 조롱입니다.

// spyController will use real methods expect for postCall() 
SimpleController spyController = Mockito.spy(new SimpleController()); 
Mockito.doReturn("mockedString").when(spyController).postCall(); 

2) WebUtil.post (.....) 그러나 나는 mockito가 정적 메서드를 조롱 할 수 방법을 모르겠어요.

이 Mockito 불가능하지만,이 작업 arrounds이 있습니다 : 정적 조롱을 허용

  1. 사용 PowerMock는.
  2. 정적 메서드를 직접 호출하지 않도록 코드를 리펙터 처리하십시오. 이것은 @ mdewit의 대답에서 이미 설명 했으므로 여기에서 세부 정보를 읽도록하겠습니다.

개인적으로는 리팩토링이 가장 깨끗한 해결책이라고 생각합니다. static dependencies is evil입니다. 어떠한 이유로 든 생산 코드를 변경할 수 없거나 원하지 않는 경우라면 Mockito.spy()보다 좋은 방법입니다.

1

당신이 AnotherController을 수정할 수 있다면, 당신은 다음을 수행 할 수 있습니다, 그리고

public class WebUtilWrapper { 
    String post(.....) { 
      return WebUtil.post(.....); 
    } 
} 

소요 그 AnotherController에 생성자를 추가 : 먼저 당신이 그렇게 같은 다른 클래스 내부 WebUtil 포장을 WebUtilWrapper를 매개 변수로 사용합니다. 이 생성자는 유닛 테스트에 사용됩니다 :

public class AnotherController { 
    private WebUtilWrapper wrapper; 

    public AnotherController() { 
      //default constructor 
      this(new WebUtilWrapper());    
    } 

    public AnotherController(WebUtilWrapper wrapper) { 
      this.wrapper = wrapper; 
    } 

    public String postCall (String url, ......) { 
      //This is the apache library to make post calls 
      return this.wrapper.post(......); 
    } 
} 

마지막으로 매개 변수화 된 생성자를 SimpleController에 추가하십시오.

public class SimpleController extends Anothercontroller { 
     public SimpleController() { 
      super(); 
     } 

     public SimpleController(WebUtilWrapper wrapper) { 
      super(wrapper); 
     } 
     . 
     . 
     . 

단위 테스트에서 WebUtilWrapper (WebUtil 대신)를 조롱 할 수 있습니다. 나머지 코드는 기본 생성자가 계속 사용할 수 있으므로 정상적으로 작동합니다.

관련 문제