0

我有一個春天mvc應用程序和使用mockito爲我的單元test.I不斷得到空指針異常,當我運行我的單元測試。 :(java.lang.NullPointerException當我運行我的單元測試 - mockito

請找到下面的方法,我的單元測試將基於:

@Controller 
public class LogInController { 

    @Autowired 
    private MessageSource messageSource; 

    @RequestMapping(method = RequestMethod.POST, value = "/login") 
    public ModelAndView validateViewLogin(@ModelAttribute Person person, 
    BindingResult result, HttpServletRequest request) { 
     ModelAndView mav = new ModelAndView(); 

     String userName = person.getFirstName(); 
     String password = person.getPassword(); 
     boolean isUserValid = false; 
     if (userName != null && password != null) { 
      isUserValid = userManagerService.validateUserLogin(userName,password); 
     } 
     if (!isUserValid) { 
      mav.addObject("failLog",messageSource.getMessage("login.user.fail", new String[] {" ", "" }, request.getLocale())); 
      mav.addObject("isUserValid", false); 
      mav.setViewName("login"); 
      return mav; 
     } 
     mav.addObject("isUserValid", isUserValid); 
     mav.setViewName("home"); 
     return mav; 
    } 

請在下面找到我的單元測試:

@Test 
public void validateViewLogin_NotValidLogin_returnsLoginPage() { 
    MockHttpServletRequest request = new MockHttpServletRequest(); 
    Person person = new Person(); 
    person.setFirstName("John"); 
    person.setPassword("123"); 
    isUserValid = false; 
    LogInController controller = new LogInController(); 

    // Inject mock user service into controller 
    UserManagerService mockUserService = mock(UserManagerService.class); 
    controller.setUserManagerService(mockUserService); 

    // Configure mock user service to accept the person 
    when(mockUserService.validateUserLogin("John", "123")).thenReturn(
      isUserValid); 

    // Attempt the validation 
    ModelAndView mav = controller 
      .validateViewLogin(person, result, request); 

    // Check the result 
    assertEquals("login", mav.getViewName()); 
} 

請在下面找到堆棧跟蹤錯誤消息時我運行上面的單元測試:

java.lang.NullPointerException 
at com.gemstone.presentation.LogInController.validateViewLogin(LogInController.java:99) 
at com.gemstone.presentation.LogInControllerTest.validateViewLogin_NotValidLogin_returnsLoginPage(LogInControllerTest.java:79) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

基本上99行如下所示返回null acco錄製堆棧跟蹤:

mav.addObject(
       "failLog", 
       messageSource.getMessage("login.user.fail", new String[] { 
         " ", "" }, request.getLocale())); 

任何爲什麼我得到空指針在這一行,請但是當我運行我的應用程序,它工作正常,並顯示我的網頁上登錄失敗消息的想法?

在此先感謝。

回答

3

我的猜測是你的messageSource爲null。你在嘲笑你的請求,但不是你的消息源,以及你正在創建登錄控制器的地方,它不會被Spring注入。

運行它會自動注入Spring。

編輯澄清:

首先,你需要能夠設置一些如何進行測試。您可以添加setter或構造函數來得到它,比如:

@Controller 
public class LogInController { 

    @Autowired 
    private MessageSource messageSource; 

    public void setMessageSource(MessageSource ms){ 
     this.messageSource = ms; 
    } 
    // ...... 
} 

然後你的測試將需要隨之改變:

@Test 
public void validateViewLogin_NotValidLogin_returnsLoginPage() { 
    MockHttpServletRequest request = new MockHttpServletRequest(); 
    Person person = new Person(); 
    person.setFirstName("John"); 
    person.setPassword("123"); 
    isUserValid = false; 
    LogInController controller = new LogInController(); 

    // Inject mock user service into controller 
    UserManagerService mockUserService = mock(UserManagerService.class); 

      /** ADDED **/ 
      MessageSource ms = mock(MessageSource.class); 

    controller.setUserManagerService(mockUserService); 
      /** ADDED **/ 
      controller.setMessageSource(ms); 

    // Configure mock user service to accept the person 
    when(mockUserService.validateUserLogin("John", "123")).thenReturn(
      isUserValid); 

      /** ADDED **/ 
      when(ms.getMessage("login.user.fail", new String[] {" ", "" }).thenReturn("message"); 

    // Attempt the validation 
    ModelAndView mav = controller 
      .validateViewLogin(person, result, request); 

    // Check the result 
    assertEquals("login", mav.getViewName()); 
} 

就免費移交這一點,所以確保我不要有任何錯別字!基本上,您可以像使用UserManagerService一樣嘗試MessageSource,它畢竟只是一個接口,並且可以用完全相同的方式進行模擬。

+0

好吧thnks很多爲您的response.But在我的情況如何嘲笑messageSource在我的單元測試請?因爲它不是我的控制器中的一個方法,並且它是ModelAndView(mav.addObject())中添加messagesource的一個方法。 – user1999453

+0

查看我的擴展答案。你嘲笑messageSource就像嘲笑其他東西一樣。 –

+0

非常感謝解釋和它的工作:) – user1999453

相關問題