온라인 기능이있는 단위 테스트 클래스


23

온라인 기능이 필요한 개인 기능이있는 클래스의 기능을 단위 테스트 할 때. 그것을 테스트하는 방법은 무엇입니까?

예를 들면 다음과 같습니다.

public class Foo
{
    public int methodA()
    {
         int val = goOnlineToGetVal();

         return val;
    }

    private int goOnlineToGetVal()
    {
        CloudService c = new CloudService();
        int oval = c.getValueFromService();
        return oval;
    }
}

함수 'methodA ()'를 테스트하려는 경우 'goOnlineToGetVal ()'을 사용하려고 시도하지만이 테스트가 기능없이 수행되면 온라인으로 전환하려고 시도합니다. 온라인에 접속하지 않고 100 % 수업에 참여하려면 어떻게해야합니까?


메소드가 클라우드 API를 호출합니까, 아니면 추가 작업을 수행합니까?
Winston Ewert


4
의존성 주입?
PhaDaPhunk

답변:


76

new CloudService()

그리고 당신의 문제가 있습니다.

최신 OO 설계에서는 이러한 종류의 종속성을 직접 구성하지 않고 전달하는 것이 좋습니다. 이것은 함수 자체 또는 건설 시간에 클래스로 전달 될 수 있습니다. 복잡한 제어가 필요한 경우 Inversion of Control 컨테이너에 의해 수집되거나 집계 될 수도 있습니다.

이 시점에서 테스트 중에 "온라인"데이터를 제공하기 위해 모의 / 가짜 서비스를 전달하는 것은 매우 사소한 일이되었습니다. 또한 소프트웨어가 충분히 유연 해져 일부 (정부?) 고객이 와서 클라우드를 가치에 사용하고 싶지 않은 경우 신속하게 조정할 수 있습니다. 또는 한 클라우드 공급자를 다른 클라우드 공급자로 덤프하려고합니다. 또는...


7
나는 의존성 주입이 무엇인지 이해하는 데 훨씬 더 가깝다고 생각합니다.
marczellm

애플리케이션에 필요한 모든 인스턴스를 생성하기에 가장 좋은 장소는 어디입니까? 가능한 한 내 응용 프로그램의 상단에 가깝습니까? 지금까지 의존성 주입 만 적용 할 수 있습니다. 언젠가 인수로 전달하지 않고 직접 인스턴스를 작성해야합니다.
Paul

3
@Paul-그것은 달려 있습니다. 필자의 경험에 따르면 응용 프로그램은 종종 이진 트리처럼 보입니다. 하나의 클래스 / 함수 / 모듈은 둘을 결합하여 좀 더 복잡한 동작을 제공합니다. 이러한 "접착제"클래스 중 하나는 구체적인 구현을 지정하는 클래스입니다. 이는 구체적인 구현에 사용됩니다.이 구현은 다른 것을 사용하여이를 결합하고, 결국에는 ... 일관되게. "최상의"장소는 코드가 수행하지 말아야 할 일을 알거나하지 않고도 코드가 필요한 작업을 수행 할 수있는 곳입니다. 다를 수 있습니다.
Telastyn

2
@Paul 일반적으로 응용 프로그램은 직접 테스트되는 "라이브러리"로 구분되며 이러한 종류의 의존성 주입과 응용 프로그램 별 코드를 사용해야합니다. 후자는 일반적으로 일부 GUI, 일부 웹 서비스 또는 사용자 제공 데이터로 라이브러리를 직접 호출하는 명령 행 인터페이스로 요약됩니다. 기본적으로 응용 프로그램 별 코드는 종속성 주입 라이브러리가 기대하는 구체적인 구현을 만듭니다.
Darkhogg

@Paul Castle Windsor, StructureMap, Ninject 및 Unity와 같은 IoC 컨테이너를 살펴보십시오. 그것들은 의존성 주입을 수행하는 유일한 방법은 아니지만, 위에서 아래로 객체 그래프를 구성하는 것에 대한 생각에서 매우 유익 할 수 있습니다.
Ben Aaronson

37

나는 이것을 다음과 같이 구현할 것이다 :

public class Foo
{
    private ICloudService cloudService;

    public Foo(ICloudService s)
    {
       cloudService=s;
    }

    public int methodA()
    {
         int val = goOnlineToGetVal();

         return val;
    }

    private int goOnlineToGetVal()
    {
        int oval = cloudService.getValueFromService();
        return oval;
    }
}

인터페이스 ICloudService는 테스트 용 모의 또는 "실제"클라우드 서비스로 구현할 수 있습니다. 의 인스턴스를 new CloudService()호출 할 때 마다 인스턴스화 가 필수 getValueFromService이거나 CloudService변경 될 수없는 타사 API에서 생성 된 경우 래퍼를 구현 ICloudService하고 적절한 호출 에서 파생하여 호출합니다.


1
이것은 분명히 갈 길입니다. 테스트를 완벽하게 제어 할 수있는 인터페이스를 조롱 할 수있는 클래스 라이브러리가 있습니다.
Greg Burghardt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.