2

I've implemented a class to read from RSS 2.0 and Atom 1.0 feeds. I want to write some unit tests in order to verify functionality. Here is the feed reader section of my code:

private String readFeed(final String url) throws IOException
{
    final StringBuilder builder = new StringBuilder();
    final URL feedUrl = new URL(url);
    final BufferedReader in = new BufferedReader(
        new InputStreamReader(feedUrl.openStream()));

    String input;
    while ((input = in.readLine()) != null)
    {
        builder.append(input);
    }
    in.close();

    return builder.toString();
}

After some research, I figured the best way to test would be to have a sample feed as an XML file in my project resources directory.

I've created a example file "resources/rss2-0.xml"

I'm sending in the following value to the readFeed function, "resource:///rss2-0.xml", and I keep receiving java.net.MalformedURLException: unknown protocol: resource

This is my first time using a URL pathway to load from a resource. From what I can tell, resource seems like it should be a valid protocol. Anyone have any ideas what I may be doing wrong or other ways to go about this?

Eddie D
  • 339
  • 1
  • 5
  • 16

2 Answers2

2

If you want to deal with path using your local file system, the Path class is best suited for this task.

An object that may be used to locate a file in a file system. It will typically represent a system dependent file path.

You can use it like so :

Path path = FileSystems.getDefault().getPath("/resources/rss2-0.xml");
BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);

If your really want to deal with URL, the protocol you're looking for is simply "file". So it would be file:///rss2-0.xml instead of resource:///rss2-0.xml and even file:/resources/rss2-0.xml to be exact.

Note that in your case, you will indeed have to deal with URLs sooner or later, but when working on local tests, using the Path class will save you troubles. If you want another alternative, try the URI class. Since an URI is an identifier (see difference between URI and URL) it can identify either an URL or a Path an may serve as a bridge between your production code which will ultimately deal with URLs and your test code where the Path class could be best put in use.

For example :

public interface FeedReader {
    String readFeed(final URI uri);
}

And 2 implementations, one for testing locally :

public class LocalFeedReader implements FeedReader {

    @Override
    public String readFeed(final URI uri) {
        // URI -> Path
        // then dealing with Path to target local rss2-0.xml file
    }
}

And one for production code :

public class WebFeedReader implements FeedReader {

        @Override
        public String readFeed(final URI uri) {
            // URI -> URL
            // then dealing with URL to target real resources
        }
    }
Community
  • 1
  • 1
m4rtin
  • 2,235
  • 19
  • 33
1

The java docs say that only http, https, file, and jar are "guaranteed" to exist on the search path for protocol handlers. Others only "may" be supported.

http://docs.oracle.com/javase/8/docs/api/java/net/URL.html#URL-java.lang.String-java.lang.String-int-java.lang.String-

It looks like if you want a custom handler that isn't supported in your java distribution, you'll have to create one.

http://mjremijan.blogspot.com/2012/02/create-your-own-java-url-handlers.html

Maggy May
  • 135
  • 7