I have code similar to this
class Util{
public String transform(String str);
//lots of logic including ajax calls
return("Modified"+str);
}
public caseChange(String str){
//lots of logic including ajax calls
return str.toUpperCase()
}
class TextParser extends Util{
public String parse(str)
//lots of logic to modify str
str = caseChange(str);
//some more logic to modify str
return transform(str);
}
Is there anyway to mock the caseChange and transform methods to return some mocked data and prevent a call to the superclass when i call
String result = new TextParser().parse("hello")
in the unit test class to assert result.
The transform and changeCase are over simplified in my example. In reality they perform ajax calls and there is a ton of other logic. I want to mock them out so that can unit test just this part an then unit test the super methods later
In your given example: you simply don't do that. Your methods are only working on your inputs; so it should absolutely not matter where those methods are implemented.
In other words: it seems most appropriate for you to focus on contract checking tests only. Like:
@Test
public testWhatever() {
assertThat(new TextParser.parse("hello"), is("expected output"));
}
Yes, you can probably mock such things using Mockito/Powermock; but you shouldn't! You see, your production code is directly calling those methods; so you want to test that calling parse gives you expected results (while using all the code that will also run in a production setup!)
Edit: given your comment about that methods being "complicated". Then I suggest: do not use inheritance here. You should not make class B a subclass of A just to have easy access to some methods. In other words: inheritance is about modeling an IS-A relation. So, a TextParser is a Util ? Doesn't sound very convincing.
Thus: you better turn to composition here. Your TextParser should use a Util object. And that one can be provided via dependency injection; and your need to mock with inherited methods vanishes completely!
You may need to create another subclass like
class TextParserForTest extends TextParser {
@Override
public String parse(String str) {
super.parse(str);
}
@Override
public String caseChange(String str) {
return "whatever";
}
}
edit : use mockito to this :
import static org.mockito.Mockito.*;
import org.junit.Test;
@Test
public void test() {
TextParser tp = mock(TextParser.class);
// all the methods that you want to test
when(tp.parse(any())).thenCallRealMethod();
when...
// all the methods that you want to mock
when(tp.caseChange(any()).thenReturn("whatever");
when...
}
You can use the spy functionality of Mockito. The spy calls real methods unless they are stubbed.
@Test
public void testParse() {
TextParser textParser = Mockito.spy(new TextParser());
when(textParser.caseChange(Matchers.anyString())).thenReturn("mocked");
Assert.assertEquals("Modifiedmocked", textParser.parse("hello"));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.