8

I want to check the IOException class in JUNIT testing. Here is my code:

public void loadProperties(String path) throws IOException {
  InputStream in = this.getClass().getResourceAsStream(path);
  Properties properties = new Properties();
  properties.load(in);
  this.foo = properties.getProperty("foo");
  this.foo1 = properties.getProperty("foo1");
}

when I try to give false properties file path it gives NullPointerException. I want to get IOException and Junit test for it. Thank you very much for your help.

Thomas
  • 87,414
  • 12
  • 119
  • 157
user6090970
  • 185
  • 1
  • 3
  • 14
  • 1
    Please show the code for how you are invoking this method. [According to the doc](https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResourceAsStream(java.lang.String)) it should only throw an NPE if `path` is `null`. – Andy Turner Apr 05 '16 at 14:30
  • Are you willing to use some mocking tool? Otherwise it will be unecessarily complex. – dambros Apr 05 '16 at 14:34
  • Yes, I am planning to use the Mockito. I am confused to write the mock for void method. It would be really helpful for me if you could provide me the scenario in which I can mock . Your help is really appreciated. – user6090970 Apr 05 '16 at 14:37
  • Possible duplicate of [Force IOException during file reading](http://stackoverflow.com/questions/2566755/force-ioexception-during-file-reading) – Sendhilkumar Alalasundaram Apr 05 '16 at 15:17
  • 1
    Why do you want to test that? Obviously, *this* code documents that it may throw an IOException, but it's not actually generating the exception itself. That's coming from the underlying file IO system. I don't see why you would unit test that. – sisyphus Apr 05 '16 at 15:26
  • 1
    What is it you actually want to test? By that I mean what is the /behaviour/ you want to see, not the implementation – tddmonkey Apr 05 '16 at 20:38

3 Answers3

2

Try this

public TestSomeClass
{
    private SomeClass classToTest; // The type is the type that you are unit testing.

    @Rule
    public ExpectedException expectedException = ExpectedException.none();
    // This sets the rule to expect no exception by default.  change it in
    // test methods where you expect an exception (see the @Test below).

    @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.
    }
}

Some reading: jUnit 4 Rule - scroll down to the "ExpectedException Rules" section.

DwB
  • 37,124
  • 11
  • 56
  • 82
0

Check this answer. In short: you can mock the resource that you want to throw an exception and throw the exception by the mock in your tests. Mockito framework might help you with that. The details are under the link I have provided earlier

jjd
  • 2,158
  • 2
  • 18
  • 31
-1

Not sure how we simulate the IOException with the current implementation but if you refactor the code in something like this:

public void loadProperties(String path) throws IOException {
    InputStream in = this.getClass().getResourceAsStream(path);
    loadProperties(in);
}

public void loadProperties(InputStream in) throws IOException {
    Properties properties = new Properties();
    properties.load(in);
    this.foo = properties.getProperty("foo");
    this.foo1 = properties.getProperty("foo1");
}

And create a mocked InputStream, something like this:

package org.uniknow.test;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;

public class TestLoadProperties {

   @test(expected="IOException.class")
   public void testReadProperties() throws IOException {
       InputStream in = createMock(InputStream.class);
       expect(in.read()).andThrow(IOException.class);
       replay(in);

       // Instantiate instance in which properties are loaded

      x.loadProperties(in);
   }
} 

WARNING: Created above code on the fly without verifying it by compiling so there might be syntax faults.

uniknow
  • 938
  • 6
  • 5
  • Instead of easymock one could use the same test case as above with easymock by replacing the easymock import statements by `import static org.mockito.Mockito.*;` and have within testReadProperties `InputStream in = mock(InputStream.class); when(in.read()).thenThrow(new IOException());` – uniknow Apr 06 '16 at 07:46