2016-08-04 16 views
0

Mockitoを使用してSpring Controllerをテストしようとしています。私はquestionとしてwhen()としても使用されているオブジェクトを嘲笑しましたが、私はまだNULLポインタ例外に直面しています。この例外を解決する方法を提案してください。Spring Controller Mockito、Null Pointer例外を使用したテスト

Github repository of this project

にリンクされている特定の行NULLポインタが

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

である私はsimpleCategoryDAOを嘲笑し、getAllCategories()のためのリストを返すためにwhen()を使用しています。

試験方法:コントローラの

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



} 

コード

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

例外:

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] 

答えて

1

問題は、あなたのtest class Before method you are instantiating new controller

であります私はセッターここ注入ないフィールド注入を使用してい

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

注意:ここでは

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

は私がController

コントローラクラスのテストを行う方法です。コンストラクタインジェクションを使用することもできます(私にとっては好ましい方法です)。あなたに

クラス

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

がテストにBefore methodを見てみましょテストします。私は、私が作成した、その後、私は、コントローラの同じインスタンスを使用してMockMvcを作成していのコントローラ新しいインスタンスにmocked DAOを設定しています。

+0

'mockMvc'を使わずに直接' CategoryController'メソッドを呼び出すことで簡単にテストすることはできませんか?また、 '@ RequestMapping'のようなアノテーションの存在は、カスタムアサーションメソッドによって確認できます。ちょうど不思議に思っています... –

+0

あなたはmockmvcなしでコントローラの簡単なテストを行うことができます。このメソッドはコントローラメソッドをmockmvcではなく単純なコンポーネントとしてのみテストします。ここでハンドラー –

+0

の実際の呼び出しをシミュレートしていますが、実際にハンドラーへの実際の呼び出しをシミュレートすると正確に何が得られますか? –

関連する問題