Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a unit test to cover the case where an IOException is thrown?

I have the following class:

    public class FileLoader {   

         private Map<Brand, String> termsOfUseText = new HashMap<Brand, String>();

         public void load() {
            for (Brand brand : Brand.values()) {
                readAndStoreTermsOfUseForBrand(brand);
            }
         }

         private void readAndStoreTermsOfUseForBrand(Brand brand) {
            String resourceName = "termsOfUse/" + brand.name().toLowerCase() + ".txt";          
            InputStream in = this.getClass().getClassLoader().getResourceAsStream(resourceName);            
            try {
                String content = IOUtils.toString(in);          
                termsOfUseText.put(brand, content);
            } catch (IOException e) {
                throw new IllegalStateException(String.format("Failed to find terms of use source file %s", resourceName),e);
            }
         }

        public String getTextForBrand(Brand brand) {
            return termsOfUseText.get(brand);
        }
    }

Brand is an enum, and I need all the valid .txt files to be on the classpath. How do I make the IOException occur, given that the Brand enum contains all the valid brands and therfore all the .txt files for them exist?

Suggestions around refactoring the current code are welcome if it makes it more testable!

like image 687
JMM Avatar asked Jul 15 '11 00:07

JMM


People also ask

How do I write a test case for IOException?

@Test public void testxyz() { expectedException. expect(IOException. class); classToTest. loadProperties("blammy"); } @Before public void preTestSetup() { classToTest = new SomeClass(); // initialize the classToTest // variable before each test. } }

How do you handle IOException in JUnit?

JUnit provides an option of tracing the exception handling of code. You can test whether the code throws a desired exception or not. The expected parameter is used along with @Test annotation. Let us see @Test(expected) in action.

How do you test if an illegal argument exception is thrown?

When an IllegalArgumentException is thrown, we must check the call stack in Java's stack trace and locate the method that produced the wrong argument. The IllegalArgumentException is very useful and can be used to avoid situations where the application's code would have to deal with unchecked input data.


1 Answers

Three options I see right off:

  1. Use PowerMock to mock IOUtils.toString(). I consider PowerMock to be quite a last resort. I'd rather refactor the source to something a little more test-friendly.
  2. Extract the IOUtils call to a protected method. Create a test-specific subclass of your class that overrides this method and throws the IOException.
  3. Extract the InputStream creation to a protected method. Create a test-specific subclass to override the method and return a mock InputStream.
like image 69
Ryan Stewart Avatar answered Oct 29 '22 11:10

Ryan Stewart