UnitTest a helper class (not controller, not service,
At the begin I need to say that I read a lot of posts for example: When should I mock? or Should I mock all the dependencies when unit testing?
I also read an article about "How to test Controller in SPRING" or "How to test service Layer".
But right now I want to test a "Helper class" for my "controller" (I'm not sure if there is a difference).
My entities classes looks like this:
topics 1:n posts 1:n comments 1:n time.
lets look at the method I want to test:
void parseToModel(Map<Integer, TimeForm> mapToTime, Time time) {
mapToTime.putIfAbsent(time.getComment().getId(), new TimeForm(time.getComment().getPost().getTopic().getName(),
time.getComment().getPost().getName(),
time.getComment().getName(),
new ArrayList<>()));
}
Like you notice here method have two parameters one is a map (Integer and TimeForm) and time.
It means that to make this test I need to create testObject of Time where I need to set all fields from the method? e.g.
Time time = new Time();
time.getComment().setId();
time.getComment().getPost().getTopic().setName();
time.getComment().getPost().setName();
time.getComment().setName();
return time;
Like you can notice times need comment, comments need a post, and posts need a topic. This means I need to create all of them? Can you explain me what I'm doing wrong?
@RunWith(MockitoJUnitRunner.class)
public class helperTest{
//given
final TimeController timeController = new TimeController(Mockito.mock(TimeService.class));
Map<Integer, TimeForm> testMap = new HashMap<>();
Time testObject = generateSimpleTestObject();
@Test
public void parse() {
//when
timeController.parseToModel(testMap, testObject);
//then
Assert.assertEquals(testMap.size(), 1);
}
Time generateTestObj(){
Time testObj = new Time();
time.getComment().setId("5");
time.getComment().getPost().getTopic().setName("TestingJava");
time.getComment().getPost().setName("Unit test.");
time.getComment().setName("Is it so hard?");
return time;
}
}
When I run my test with example data like upper I have a java.lang.NullPointerException.
This is an error stacktrace:
java.lang.NullPointerException at com.timeproject.time.view.HelperTest.generateSimpleTestObject(HelperTest.java:40) at com.timeproject.time.view.HelperTest.(HelperTest.java:26) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217) at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Update: Test passed after editing my testObject method that way:
Time generateSimpleTimeTestObject() {
Time time = new Time();
Comment comment = new Comment();
Project project = new Project();
Topic topic = new Topic();
time.setComment(comment);
time.getComment().setPost(post);
time.getComment().getPost().setTopic(topic);
time.getComment().setId(999);
time.getComment().getPost().getTopic().setName("Topic name");
time.getComment().getPost().setName("Post name");
time.getComment().setName("Comment name");
return time;
}
But I'm still not sure if its a right way (if some1 could confirm in a comment it's a 100% right way to do it I would've be grateful.)