How do you unit test for methods that take a lot of time?

I am new to unit test. There is a method that looks like this:

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

And I write unit test:

@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");
}

But if Internet access takes a lot of time. I usually want to use a local HTML file to test this method, but sometimes I test the web version.

Any suggestion?

+3
source share
4 answers

Your unit test should not check if the internet is working. You must provide some layouts of the HTML files and specify those used for the test. Since you are dealing with a URL, you can specify a path, for example "file:///path/to/test.html", instead of a web URL.

+3
source

Short answer: dependency inversion.

A slightly longer answer:

, -, , fetchSource; , . , fetchSource - , , , , . , "" , "fecht", .

fetchSource, , (parseHtmlToImage?). :

  • imageFetcher , URL-, ( ); "" .
  • , , , , , , .

( ).

+3

-

  • , , ; , (. Mockito Easymock ), fetchURL , ;

  • , fetchURL , , unit test , . , ​​, .. , . , .

+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 . ( ) , " Web Utils ". ImageFetcher utils.

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;
    }
}

Image Fetcher is currently focusing on developing which image to use. You no longer need to care about how you get this image from the network. WebUtils can mock unit tests.

@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);
}
+1
source

All Articles