UnitTest是辅助类(不是控制器,不是服务等)

时间:2018-02-07 08:44:08

标签: java spring unit-testing

UnitTest辅助类(不是控制器,不是服务,

一开始我需要说我读了很多帖子,例如: When should I mock? 要么 Should I mock all the dependencies when unit testing?

我还阅读了一篇关于"如何在SPRING中测试控制器的文章"或"如何测试服务层"。

但是现在我想测试一个" Helper类"对于我的"控制器" (我不确定是否存在差异)。

我的实体类看起来像这样:

topics 1:n posts  1:n comments 1:n time.

让我们看看我想测试的方法:

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<>()));
}

就像你注意到这里方法有两个参数,一个是map(Integer和TimeForm)和时间。

这意味着要进行此测试,我需要创建Time的testObject,我需要在该方法中设置所有字段?     e.g。

Time time = new Time();
time.getComment().setId();
time.getComment().getPost().getTopic().setName();
time.getComment().getPost().setName();
time.getComment().setName();
return time;

就像你可以注意到时间需要评论,评论需要一个帖子,帖子需要一个主题。 这意味着我需要创建所有这些? 你能解释一下我做错了吗?

@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;
    }   
}

当我使用像upper这样的示例数据运行我的测试时,我有一个java.lang.NullPointerException。

这是一个错误堆栈跟踪:

  

java.lang.NullPointerException at   com.timeproject.time.view.HelperTest.generateSimpleTestObject(HelperTest.java:40)     在com.timeproject.time.view.HelperTest。(HelperTest.java:26)     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native   方法)at   sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)     在   sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)     在   org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)     在   org.junit.runners.BlockJUnit4ClassRunner $ 1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)     在   org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)     在   org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)     在   org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)     在   org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)     在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)at at   org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)at at   org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at at   org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)at at   org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)at at   org.junit.runners.ParentRunner.run(ParentRunner.java:363)at at   org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)     在   org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)     在org.junit.runner.JUnitCore.run(JUnitCore.java:137)at   com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)     在   com.intellij.rt.execution.junit.IdeaTestRunner $ Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)     在   com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)     在   com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

更新: 在编辑我的testObject方法之后测试通过:

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;
}

但是我仍然不确定它是否是正确的方式(如果有人能够在评论中确认它是100%正确的方式,我会感激不尽。)

1 个答案:

答案 0 :(得分:1)

  

这意味着我需要创建所有这些?

  

你能解释一下我做错了吗?

概念性?什么都没有。

您的参数Time看起来像数据传输对象。这有点特殊,所以我们通常不会将demeter的定律(不要与陌生人交谈!)应用于他们。

另一方面,您可能希望隐藏信息隐藏(并因此 LoD ,以便您通过添加来避免&#34;链破坏&#34; 委派方法Time类。

然后Time有点像&#34; hybrit&#34;你会创建一个它的模拟(它不会为&#34;纯&#34; DTO而做,并且不需要配置Time对象的所有依赖...