웹 서비스 호출이 필요한 클래스를 어떻게 단위 테스트 할 수 있습니까?


21

일부 Hadoop 웹 서비스를 호출하는 클래스를 테스트하려고합니다. 코드는 거의 형태입니다.

method() {
    ...use Jersey client to create WebResource...
    ...make request...
    ...do something with response...
}

예를 들어 디렉토리 생성 방법, 폴더 생성 방법 등이 있습니다.

코드가 내가 제어 할 수없는 외부 웹 서비스를 다루고 있다고 가정하면 어떻게 이것을 단위 테스트 할 수 있습니까? 웹 서비스 클라이언트 / 응답을 시도하고 조롱 할 수는 있지만 최근에 많이 본 지침을 위반했습니다. "소유하지 않은 개체를 조롱하지 마십시오". 더미 웹 서비스 구현을 설정할 수 있습니다. 여전히 "단위 테스트"를 구성합니까, 아니면 통합 테스트입니까? 이 낮은 수준에서 단위 테스트를 할 수 없습니까? TDD 실무자는 어떻게 이것을 할 것입니까?


5
소유하지 않은 것을 조롱하지 않는 것에 대한 지침을 어디에서 보았습니까? 그것은 당신이 물건을 조롱해야하는 큰 이유 인 것 같습니다 ...
Thomas Owens


1
@ChrisCooper : 마지막 링크가 매우 오래된 것임을 지적 할 수 있습니다 (2007 년부터). 그 이후로 많은 것이 바뀌 었습니다. 나는 단순히 조롱 프레임 워크 나 메타 프로그래밍을 사용하여 리턴 값을 설정하는 대신 행동을 실제로 구현해야했을 때 조롱이 훨씬 어려워 졌다는 느낌을 받았다.
c_maker

답변:


41

내 생각에 통합 테스트와는 반대로 단위 테스트 인 경우 웹 서비스 호출을 조롱해야합니다.

단위 테스트는 외부 웹 서비스가 작동하는지 또는 웹 서비스와의 통합이 올바른지 테스트하지 않아야합니다. TDD에 대해 너무 독단적이지 않고 단위 테스트를 통합 테스트로 전환하면 부작용이 더 느리게 진행되고 빠른 단위 테스트 를 원한다는 점에 유의하십시오 .

또한 웹 서비스가 일시적으로 다운되거나 제대로 작동하지 않으면 유닛 테스트가 실패합니까? 옳지 않은 것 같습니다. 단 하나의 이유로 유닛 테스트에 실패해야합니다. 해당 "유닛"의 코드에 버그가있는 경우.

여기서 관련된 코드의 유일한 부분은입니다 ...do something with response.... 나머지를 조롱하십시오.


2
모의 객체 서명 및 반환 값을 해당 서비스에 대한 불가피한 변경 사항을 통해 Hadoop 웹 서비스에서 생성 된 값과 동기화 상태로 유지해야합니다.
pcurry

하둡과 같은 상용 구성 요소를 테스트 할 가치는 거의 없습니다. 그러나 다른 팀이나 조직에서 제공 한 사용자 지정 웹 서비스를 호출하는 경우 자체 방어로 테스트를 작성해야 할 수 있습니다. 그렇게하면 문제가 발생했을 때 문제가 코드인지 웹 서비스인지 신속하게 확인할 수 있습니다. 이것은 자동으로 실행되는 단위 테스트가 아닙니다. 필요에 따라 실행하는 것은 진단입니다.
케빈 클라인

@kevincline 나는 당신이 제안하는 시험의 필요성에 전적으로 동의하며, 실제로 시험을 내 일에 쓰고 유용하다고 입증했습니다. 그러나 그들은 정의에 의한 것이 아니라 단위 테스트가 아닙니다. 문제는 다음과 같습니다. 정확히 실패한 것은 무엇입니까? 단위 테스트에서 필요에 따라 별도로 테스트하지 않습니다.
Andres F.

1
@AndresF .: 우리가 폭력적으로 동의하고 있다고 생각합니다. "이 [진단]은 단위 테스트가 아닙니다 ..."
kevin cline

@kevincline 맞아! 귀하의 의견을 잘못 읽었습니다. 죄송합니다.
Andres F.

5

단위 테스트를 할 때 "소유하지 않는 물건을 조롱하지 마십시오"에 동의하지 않습니다.

존재의 목적은 우리가 소유하지 않을 모듈, 라이브러리, 클래스가 있다는 사실입니다.

귀하의 시나리오에 대한 제안은 웹 서비스 호출을 조롱하는 것입니다.

모듈에 데이터를 다시 반환하도록 모의를 설정하십시오.
반환 된 데이터가 null 인 경우, 반환 된 데이터가 유효한 경우 등 모든 시나리오를 다루어야합니다.

또한 귀하가 소유 한 코드에 대해 개발자로서의 책임은 작성하는 코드가 모든 시나리오에서 예상대로 수행되도록하는 것입니다.


1

이 테스트에는 EasyMock과 같은 것을 사용합니다. 모의 프레임 워크는 클래스의 외부 종속성을 제거하는 이상적인 방법이며 테스트 중에 외부 종속성의 결과를 완전히 제어 할 수 있습니다. 예제를 조금 확장하려면 :

class WebClass {

private WebServiceInterface webserviceInterface;

    void method(){
        R result = webServiceInterface.performWebServiceCall();
        ... do something with result
    }

    public void setWebServiceInterface(WebServiceInterface webServiceInterface){
        this.webServiceInterface = webServiceInterface;
    }
}


interface WebServiceInterface {

   R performWebServiceCall();

}


class WebClassTest {

private WebServiceInterface mock;    
private R sampleResult = new R();

    @Before
    public void before(){
        mock = EasyMock.createMock(WebServiceInterface.class);
    }


    @Test
    public void test() {
        WebClass classUnderTest = new WebClass();
        EasyMock.expect(mock.performWebServiceCall()).andReturn(sampleResult);
        classUnderTest.setWebServiceInterface(mock);
        classUnderTest.method();
        EasyMock.verify(mock);
    }
}

가장 먼저해야 할 일은 Jersey를 사용하여 WebResource를 가져 와서 웹 서비스를 별도의 클래스로 호출하는 클래스의 논리를 추출하는 것입니다. 이 클래스에 대한 인터페이스를 만들면 동작을 지시 할 수있는 모형을 만들 수 있습니다.

이 인터페이스가 생성되면 EasyMock을 사용하여 모의 객체를 생성하여 테스트 케이스에 따라 지정된 객체를 반환합니다. 위의 예는 기본 모의 테스트를 구성하는 방법과 인터페이스 작동 방식을 단순화 한 것입니다.

모의 프레임 워크에 대한 자세한 내용은 이 질문을 참조하십시오 . 또한이 예제에서는 Java를 사용한다고 가정하지만 모의 프레임 워크는 모든 언어로 제공되며 다르게 구현되지만 일반적으로 동일한 방식으로 작동합니다.


1

이 경우 Mocks를 사용할 수 있지만 필요하지 않습니다. 단위 테스트 method()대신 응답을 처리하는 부분 만 단위 테스트합니다.

ResponseData(어떤 종류의 것이 든 적절한) 함수를 추출한 다음 조치를 수행하십시오.

조롱하는 대신 이제 ResponseData 객체를 생성하여 전달하면됩니다.

당신은 떠날 수 호출 전체 통합 테스트에 대한 봉사를 - 즉 다룰 것입니다 method()


0

내가 한 일과 작동합니다.

  1. 모든 코드가 프록시를 통해 웹 서비스를 호출하도록합니다.
  2. 프록시는 프록시 사용 여부를 정적으로 알고 클래스를 리디렉션하는 클래스를 호출합니다. Mocks는 각 요청에 대해 지정된 응답을 반환하는 HashMap입니다.
  3. 이 순서대로 테스트를 여러 번 실행하십시오.

3.1 먼저 모든 웹 서비스가 테스트됩니다. 각 머신에서 개발자 머신까지. 이들은 실제 웹 서비스이지만 개발 환경에서 실행됩니다. 즉, 웹 서비스는 다운되거나 절대 잘못된 값에 응답 할 수 없습니다. 그렇지 않으면 모든 개발자가 컴파일 할 수 없다고 불평하기 때문입니다.

3.2 그런 다음 응용 프로그램 내부의 모든 단위 테스트가 실행됩니다. 즉, 모든 웹 서비스는 3.1과 동일한 테스트 (모두 전달해야하며 그렇지 않은 경우 모의가 잘못됨)를 실행하고 실제 응용 프로그램에서 실제로 사용되는 것처럼 호출되어 테스트되고 테스트됩니다. 모의가 틀린 경우 3.1에서 테스트를 실행하고 해당 값 (요청, 응답)을 HashMap에 기록 할 수 있습니다.

3.3 3.2와 동일한 테스트가 실행되지만 이번에는 개발 환경에서 실행되는 실제 웹 서비스에 대해 수행됩니다.

이러한 모든 작업이 완료된 후 실제 프로덕션 환경에서는 각 웹 서비스에 대한 실제 주소 만 제공하면됩니다. 바라건대 이것은 구성을 너무 많이 변경하지 않아도되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.