Given the source code below, how could I effectively unit test the
Message class, the inner class of
MainMsg? The challenge for this use case is
Message class doesn't have any public interface that could access from outside world, the only entry is from
MainMsg's
addMessage(). How could I return a fake data when
getMsgList() is called? Or I shouldn't mock
Message class actually, just instantiate a new value is more than enough.
public class MySystem {
public static void getMessage(MainMsg mm) {
if( mm.getMsgList().size() > 0 ) {
…
…
}
}
}
public class MainMsg {
private List<Message> msgList = new ArrayList<Message>();
public class Message {
private String str;
Message(String str) {
this.str = str;
}
}
public void addMessage(String content) {
msgList.add(new Message(content));
}
public List<Message> getMsgList() {
return msgList;
}
}
According to the advice from expert, I shouldn’t mock the inner class, whereas I should create a real value of it. But how? After a long R&D, I found
EasyMock could handle this very well. In my unit test class, this is how I did it:
@RunWith(PowerMockRunner.class)
@PrepareForTest({MySystem.class})
public class MySystemTest {
private MainMsg mm;
@Test
public void testSendMessage () throws IOException {
mm = PowerMock.createPartialMock(MainMsg.class, "getMsgList");
EasyMock.expect(mm.getMsgList()).andStubAnswer(new IAnswer<List<Message>>() {
@Override
public List<Message> answer() throws Throwable {
Whitebox.setInternalState(mm, new ArrayList<Message>());
mm.addMessage("message_A");
List<Message> fakeMsgList = Whitebox.getInternalState(mm, "msgList");
return fakeMsgList;
}
});
MySystem.getMessage(mm);
}
}