3

I try to mock getResourceAsStream method which I invoke in constructor.

public Conn() {
    stream = Conn.class.getClass().getResourceAsStream(PATH);
}

For mock framework I prefer Mockito + PowerMockito.

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Conn.class)
    public class ConnTest {

        @Mock
        private InputStream streamMock;

        private Conn conn;

        @Before
        public void before() {
            initMocks(this);
        }

        @Test
        public void test() {    
            PowerMockito.mockStatic(Conn.class);
            PowerMockito.when(Connector.class.getResourceAsStream("/prop.properties")).thenReturn(streamMock);
            conn = new Conn();
        }

        @After
        public void after() {
            reset(streamMock);
        }
     }

But method thenReturn doesn't return a mock. How can I fix it?

barbara
  • 3,111
  • 6
  • 30
  • 58

3 Answers3

1

You can abstract getting the resource to a class.

class StreamFetcher {

InputStream fetchStream(String path) {
return StreamFetcher.class.getClass().getResourceAsStream(path);
}

}

and in your class

class Conn {
public Conn(StreamFetcher streamFetcher) {
    stream = streamFetcher.fetchStream(PATH);
}
}

That way you don't even have to do a mock - you can create your own impl for tests that does whatever you need it to do.

Also you can actually abstract more and maybe process the Stream somehow. I don't know the business context so can't really help you on this one.

Marcin Grzejszczak
  • 10,624
  • 1
  • 16
  • 32
0

It doesn't return a mock because the code-under-test new Conn() does not call

Connector.class.getResourceAsStream(...)

it calls

Conn.class.getResourceAsStream(...)

Your code worked by changing the method stubbing to:

PowerMockito.when(Conn.class.getResourceAsStream("/prop.properties")).thenReturn(streamMock);
Jose Tepedino
  • 1,524
  • 15
  • 18
0

You can do like below:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Class.class)
    public class ConnTest {

        @Mock
        private InputStream streamMock;

        private Conn conn;

        @Before
        public void before() {
            initMocks(this);
        }

        @Test
        public void test() {    
            PowerMockito.mockStatic(Class.class);
            PowerMockito.when(Connector.class.getClass().getResourceAsStream("/prop.properties")).thenReturn(streamMock);
            conn = new Conn();
        }

        @After
        public void after() {
            reset(streamMock);
        }
     }

Here you are stubbing resource on top of a class object, that is why Class.class you need to prepare for test by using @PrepareForTest(Class.class) and PowerMockito.mockStatic(Class.class);.

I am not sure whether it'll work for constructor or not but for a method which is calling getClass.getResourceAsStream("anyString") it's working fine(I have tested).

Chandra Sekhar
  • 16,256
  • 10
  • 67
  • 90