2016-08-04 48 views
0

Ich versuche einen Federcontroller mit Mockito zu testen. Ich habe das Objekt auch when() als question verspottet verspottet, aber ich bin immer noch mit der Nullzeiger Ausnahme konfrontiert. Bitte schlagen Sie einen Weg vor, um diese Ausnahme zu lösen.Spring Controller Test mit Mockito, Nullzeiger Ausnahme

Github repository of this project

Die bestimmte Zeile Null-Zeiger verknüpft ist

modelMap.put("categories", simpleCategoryDAO.getAllCategories());  

I verspottet haben simpleCategoryDAO und verwendet when() eine Liste für getAllCategories() zurückzukehren.

Testmethode:

@RunWith(MockitoJUnitRunner.class) 
public class CategoryControllerTest { 

    private MockMvc mockMvc; 

    @InjectMocks 
    private CategoryController categoryController; 

    @Mock 
    private SimpleCategoryDAO simpleCategoryDAO; 

    @Before 
    public void setup() { 
     categoryController = new CategoryController(); 
     mockMvc = MockMvcBuilders.standaloneSetup(categoryController).build(); 
    } 

    @Test 
    public void categories_ShouldRenderCategoriesView() throws Exception { 
     List<Category> ALL_CATEGORIES = Arrays.asList(
       new Category(1,"Funny"), 
       new Category(2,"JoyFul") 
       ); 
     Mockito.when(simpleCategoryDAO.getAllCategories()).thenReturn(ALL_CATEGORIES); 

     mockMvc.perform(get("/categories")) 
     //.andExpect((MockMvcResultMatchers.model()).attribute("categories",ALL_CATEGORIES)); 
     .andExpect(MockMvcResultMatchers.view().name("categories")); 
    } 



} 

Code of Controller

@Controller 
public class CategoryController { 

    @Autowired 
    SimpleCategoryDAO simpleCategoryDAO; 

    @Autowired 
    SimpleGifDAO simpleGifDAO; 

    @RequestMapping("/categories") 
    public String getAllCategories(ModelMap modelMap) {  
     modelMap.put("categories", simpleCategoryDAO.getAllCategories());  
     return "categories";   
    } 

    @RequestMapping("/category/{categoryID}") 
    public String getGifsByCategoryID(@PathVariable int categoryID,ModelMap modelMap){ 
     modelMap.put("gifs", simpleGifDAO.findGifsByCategoryID(categoryID));  
     modelMap.put("category",simpleCategoryDAO.getCategoryByID(categoryID)); 
     return "category"; 
    } 
} 

Ausnahme:

java.lang.NullPointerException: null 
    at com.teja.controller.CategoryController.getAllCategories(CategoryController.java:23) ~[classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73] 
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73] 
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [tomcat-embed-core-8.0.23.jar:8.0.23] 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.0.23.jar:8.0.23] 
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:144) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
    at CategoryControllerTest.categories_ShouldRenderCategoriesView(CategoryControllerTest.java:46) [classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73] 
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73] 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) [junit-4.12.jar:4.12] 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12] 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) [junit-4.12.jar:4.12] 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.12.jar:4.12] 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.12.jar:4.12] 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) [junit-4.12.jar:4.12] 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) [junit-4.12.jar:4.12] 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) [junit-4.12.jar:4.12] 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12] 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12] 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12] 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12] 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12] 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12] 
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) [mockito-core-1.10.19.jar:na] 
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) [mockito-core-1.10.19.jar:na] 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) [.cp/:na] 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na] 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na] 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) [.cp/:na] 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na] 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na] 

Antwort

1

Das Problem ist auf Ihrem test class Before method you are instantiating new controller

Hier
@Before 
    public void setup() { 
     categoryController = new CategoryController(); 
     mockMvc = MockMvcBuilders.standaloneSetup(categoryController).build(); 
    } 

ist, wie ich tun Test für Controller

Controller-Klasse:

@Controller 
public class CategoryController { 

    private SimpleCategoryDAO simpleCategoryDAO; 
    private SimpleGifDAO simpleGifDAO; 

    @Autowired 
    public void setSimpleGifDAO(SimpleGifDAO simpleGifDAO) { 
     this.simpleGifDAO = simpleGifDAO; 
    } 

    @Autowired 
    public void setSimpleCategoryDAO(SimpleCategoryDAO simpleCategoryDAO) { 
     this.simpleCategoryDAO = simpleCategoryDAO; 
    } 

    @RequestMapping("/categories") 
    public String getAllCategories(ModelMap modelMap) { 
     modelMap.put("categories", simpleCategoryDAO.getAllCategories()); 
     return "categories"; 
    } 

    @RequestMapping("/category/{categoryID}") 
    public String getGifsByCategoryID(@PathVariable int categoryID, ModelMap modelMap) { 
     modelMap.put("gifs", simpleGifDAO.findGifsByCategoryID(categoryID)); 
     modelMap.put("category", simpleCategoryDAO.getCategoryByID(categoryID)); 
     return "category"; 
    } 
} 

Hinweis Ich verwende Setter Injektion hier nicht Feldeinkopplung. Sie können auch die Konstruktorinjektion verwenden (bevorzugte Methode für mich).

In Sie testen Klasse

@RunWith(MockitoJUnitRunner.class) 
public class CategoryControllerTest { 

    private MockMvc mockMvc; 

    @Mock 
    private SimpleCategoryDAO simpleCategoryDAO; 

    @Before 
    public void setup() { 
     final CategoryController categoryController = new CategoryController(); 

     //notice here I'm setting the mocked dao here 
     // if you didn't use @RunWith(MockitoJUnitRunner.class) 
     // you can do: simpleCategoryDAO = Mockito.mock(SimpleCategoryDAO.class); 

     categoryController.setSimpleCategoryDAO(simpleCategoryDAO); 

     mockMvc = MockMvcBuilders.standaloneSetup(categoryController).build(); 
    } 

    @Test 
    public void categories_ShouldRenderCategoriesView() throws Exception { 
     List<Category> ALL_CATEGORIES = Arrays.asList(
       new Category(1, "Funny"), 
       new Category(2, "JoyFul") 
     ); 
     Mockito.when(simpleCategoryDAO.getAllCategories()).thenReturn(ALL_CATEGORIES); 

     mockMvc.perform(get("/categories")) 
       //.andExpect((MockMvcResultMatchers.model()).attribute("categories",ALL_CATEGORIES)); 
       .andExpect(MockMvcResultMatchers.view().name("categories")); 
    } 
} 

Werfen Sie einen Blick auf Before method auf Test. Ich bin die mocked DAO auf der neue Instanz von Reglereinstellung, die ich angelegt habe und dann bin ich die Schaffung MockMvcgleiche Instanz Controller.

+0

Wäre es nicht einfacher, 'CategoryController' zu testen, indem Sie seine Methoden direkt aufrufen, ohne' 'mockMvc'' zu verwenden? Und das Vorhandensein von Anmerkungen wie "@ RequestMapping" könnte durch eine benutzerdefinierte Assertion-Methode verifiziert werden. Fragen Sie sich einfach ... –

+0

Sie können den einfachen Test für den Controller ohne mockmvc tun. Diese Methode testet die Controller-Methode nur als reine Komponente und nicht als mypmvc. Hier simulieren wir den eigentlichen Aufruf an den Handler. –

+0

Ja, aber was genau bringt uns das "Simulieren des tatsächlichen Aufrufs zum Handler"? –