问题
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?
回答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.
回答2:
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);
回答3:
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).
来源:https://stackoverflow.com/questions/29043833/how-to-mock-getresourceasstream-method-using-powermockito-and-junit