2011-05-12 6 views
3

단위 테스트를 처음 사용했습니다. 이처럼 보이는 방법이다 :오랜 시간이 걸리는 방법에 대한 단위 테스트는 어떻게합니까?

public Image getImage(String url) { 
    Document pageSource = fecthSource(url); 
    Image myImage = parseHtmlToImage(pageSource); 
    return Image; 
} 

는 내가 단위 테스트 쓰기 :

@test 
public void getRightPicture() { 
    Image img = imageFetcher.getImage("http://www.123.com"); 
    assertEquals(img.sourceUrl, "http://www.123.com/456.png"); 
    Image img = imageFetcher.getImage("http://www.abc.com"); 
    assertEquals(img.sourceUrl, "http://www.abc.com/def.png"); 
} 

을하지만 시간이 오래 걸리는 경우 인터넷에 액세스 할 수 있습니다. 보통이 방법을 테스트하기 위해 로컬 HTML 파일을 사용하려고하지만 가끔 웹 버전을 테스트합니다.

의견이 있으십니까?

+0

로컬 URL을 getImage의 매개 변수로 전달할 수 있지만 특별한 경우입니다. 예를 들어, 느린 알고리즘 대신 사전 계산 된 데이터를 사용해야합니다. –

답변

3

단위 테스트에서 인터넷 작동 여부를 확인할 필요가 없습니다. 모의 HTML 파일을 제공하고 테스트 용 파일을 가리켜 야합니다. URL을 다루므로 웹 URL 대신 "file:///path/to/test.html"과 같은 경로를 지정할 수 있어야합니다.

+0

내가 원하지만 어떻게? paresHtmlToImage()를 공개해야한다는 의미입니까? –

+0

답변을 업데이트 했으므로 URL의 파일 경로를 지정할 수 있어야합니다. – WhiteFang34

+0

OP에 대한 내 의견을 참조하십시오. 편의를 위해 URL 예제를 사용합니다. –

1

여기에 두 가지 옵션이 있습니다 -

  1. 로컬 파일이 확실히 일을 빠른 방법입니다; 또한, 테스트하려는 클래스에서 fetchURL 메소드를 조롱 할 수 있도록 mock 객체 (조롱을 용이하게하기위한 Mockito 또는 Easymock 참조)를 작성하면됩니다.

  2. 웹에서 fetchURL을 원할 때 다른 테스트 종속성을 외부로 이동하기 때문에 그 시점에서 단위 테스트 이상이됩니다. 이러한 경우 부작용, 즉 네트워크 지연, 리소스 가용성 등을 처리해야합니다.이 통합 테스트를위한 한 가지 최적화는 여러 테스트가 종속 된 경우 리소스를 캐시하는 것입니다. 그렇게하면 매번 네트워크를 통해 가져올 필요가 없습니다.

+0

1에서 언급 한 라이브러리를 보게됩니다. 그러나 2를 이해할 수 없습니다. 유닛 테스트에서 로컬 버전을 테스트해야하지만 통합 버전에서 네트워크 버전을 테스트한다는 것은 무엇을 의미합니까? –

+0

예 - 당신 말이 맞습니다. 또한 fetchURL(...)있는 메서드를 테스트하는 여러 테스트를 경우 결과를 캐싱 좋습니다. – kuriouscoder

3

짧은 대답 : 의존성 반전.

다소 긴 답변 :

문제는 아마도 fetchSource가 무엇을하고 있는지와 관련된다; 세부 사항을 보지 않고이 대답은 약간의 모호함을 가져야합니다. 나는 fetchSource가 검색을 실제로 수행하기 위해 무엇인가를 호출하고 이것이 어떻게 수행되는지에 대한 세부 사항이 테스트에 관심이있는 것이 아니라고 가정합니다. 나는 또한 당신이 "fecht"라고 쓰는 모든 곳에서 "fetch"를 쓰는 것을 의미한다고 가정하고 있지만, 대답에는 특별히 중요하지 않습니다.

당신은 중요한 것을 테스트하는 데 집중할 수 있도록 fetchSource의 구체적인 비트를 추상화하고 싶습니다 (parseHtmlToImage?). 당신이 할 수있는 여러 가지 방법이 있습니다

  • , 당신은 실제로 URL을 검색되는 인터페이스의 스텁 구현하여 imageFetcher를 구축 (종속성 반전) 생성자를 통해 그것을 전달은; 당신의 그루터기는 "인터넷"의 역할을하고 미리 준비된 응답을 되돌려줍니다.
  • 인터페이스의 스텁 구현을 만들 수없는 경우 가져 오기에 사용중인 현재 인터페이스를 사용하는 프로덕션 구현이있는 어댑터 인터페이스와 테스트에 사용하는 스텁 구현을 소개하십시오.

이것은 테스트 가능한 코드를 작성하는 데있어 매우 기본적인 기술입니다 (종속성 반전 원리를 참조하십시오).위의 의존성 주입의 답변을 확장하려면

+0

> 생성자를 통해 전달합니다. "it"이란 무엇입니까? URL? 객체가 스텁 메서드를 구현합니까? (예제 코드를 조금 줄 수 있습니까? 위키에서 DIP을 읽었지 만,이 경우 어떻게 사용하는지 모르겠습니다.) –

+0

지연에 대해 사과드립니다. 여전히 새 주석을 추적하기 위해 StackExchange UI에 익숙하지 않습니다. 이 경우 "그것"은 프로덕션 코드에서 인터페이스의 프로덕션 구현이고, 테스트 코드에서 인터페이스의 스텁 구현입니다 (이 경우 인터페이스는 실제로 URI를 페치하는 세부 사항을 추상화합니다). –

1

:

그래서 당신은 :

class ImageFetcher { 
    public Image getImage(String url) { 
     Document pageSource = fetchSource(url); 
     Image myImage = parseHtmlToImage(pageSource); 
     return Image; 
    } 
    private Document fetchSource(String url) { 
     // ... Network IO etc 
    } 
    private Image parseHtmlToImage(Document pageSource) { 
     // Parsing logic 
     // Network IO 
     return image; 
    } 
} 

첫 번째 질문은 ImageFetcher "모두가 정말에 속하는 않는 것을"는 "IMO fetchSource은하지 않습니다 그 (.. 나) 다른 "웹의 Utils"클래스가 할 법한 소리에. 나는 또한 유틸 클래스에 ImageFetcher에서 이미지의 점점 이동할 것입니다.

이제
class ImageFetcher { 
    private WebUtils webUtils; 
    public ImageFetcher(webUtils webUtils) { 
     this.webUtils = webUtils; 
    } 


    public Image getImage(String url) { 
     Document pageSource = webUtils.fetchSource(url); 
     Image myImage = parseHtmlToImage(pageSource); 
     return Image; 
    } 

    private Image parseHtmlToImage(Document pageSource) { 
     imageURL = // Parsing logic 
     image = webUtils.fetchImage(imageURL); 
     return image; 
    } 
} 

이미지 가져 오기를 내가 무엇보다 사용할 이미지를 고민 중입니다. 더 이상 네트워크에서 이미지를 얻는 방법에 대해 신경 쓸 필요가 없습니다. WebUtils는 단위 테스트를 위해 조롱받을 수 있습니다.

@test 
public void getImage_ReturnsBannerImage() { 
    Image expected = // ... 


    String html = "<html><img src="fred"/>...</html>"; // Keep this short and simple. 
    mockedWebUtil.fetchSource(Any.String).returns(html); 
    mockedWebUtil.fetchImage("fred").returns(expected); 

    var subject = new ImageFetcher(mockedWebUtil); 
    var actual = subject.getImage("blah"); 

    Assert.AreEqual(expected, actual); 
} 
관련 문제