javaspringjunitvaadinspring-junit

Getting NPE while unit testing a class using JUnit, Spring 4 and Vaadin


I am trying to unit test a very basic class that is extending some classes from Vaadin framework. But I am getting NullPointerException when I run the test.

Do I need to mock the UI class? Please guide.

Error Log:

into the enter method......

java.lang.NullPointerException
    at com.jpmorgan.tss.payhub.template.views.MainView.enter(MainView.java:46)
    at com.jpmorgan.tss.payhub.template.views.MainViewTest.testEnter(MainViewTest.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    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)

MainViewTest.java

public class MainViewTest {

    @Mock
    ViewChangeListener.ViewChangeEvent viewChangeEvent = Mockito.mock(ViewChangeListener.ViewChangeEvent.class);

    @Test
    public void testEnter() {
        MainView instance = new MainView();
        instance.enter(viewChangeEvent);
        assertNotNull(instance);
    }

}

MainView.java (Class Under Test)

@Component
@Scope("prototype")
@VaadinView(MainView.NAME)
@Title("Mortgage Banking")
@Theme("PymtTemplateUI")
public class MainView extends VerticalLayout implements View {

    @PostConstruct
    public void PostConstruct() {
    }

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        System.out.println("into the enter method......");
        UI ui = UI.getCurrent();
        Navigator nav = ui.getNavigator();
        nav.navigateTo("homePageView");
    }

}

Solution

  • Do I need to mock the UI class? Please guide.

    Yes, you need to. It is actually not trivial, since you need to mock other stuff in Vaadin too. So if you want to do basic UI testing without running the application, i.e. technique called browserless testing you could study this experimental open source project

    https://github.com/mvysny/karibu-testing

    There is also a blog post that describes the principles how to mock UI and other needed Vaadin classes.

    Additionally (since the above approach do not cover integration test needs fully) or as another alternative you can instead do UI testing with Selenium or Vaadin TestBench, i.e. automated browser testing.