2013-01-22 5 views
1

나는 mockito를 처음 사용하고 있으며 사용자 유효성 검사를위한 단위 테스트를 만들고 싶다. 내가 단위 테스트를 수행 할 방법을 검색 할 수 있습니다 : 당신이 isUserValid 방법 위에서 볼 수 있듯이메서드 내의 다른 클래스에서 반환 값을 조롱하는 방법 java (mockito)

@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.setViewName("home"); 
     return mav; 
    } 
    mav.addObject("isUserValid", isUserValid); 
    mav.setViewName("login"); 
    return mav; 
} 

내가 반환에게의 ModelAndView를 테스트 할 부울 내 방법을 반환합니다.

참조하십시오 아래에있는 내 단위 테스트 :

`@Test public void testValidateOk() { 


    MockHttpServletRequest request = new MockHttpServletRequest(); 
    MockHttpServletResponse response = new MockHttpServletResponse(); 
    Person person = new Person(); 
    ModelAndView mav = new ModelAndView(); 
    mav.setViewName("login"); 

    person.setFirstName("John"); 
    person.setPassword("123"); 





    LogInController controller = new LogInController(); 

    UserManagerServiceImpl mockpdao = mock(UserManagerServiceImpl.class); 

    ReflectionTestUtils.setField(controller, "userManagerService", mockpdao); 

    // given 
    given(controller.validateViewLogin(person, result, request)).willReturn(mav); 

    // when 
    ModelAndView validateViewLogin= 
      controller.validateViewLogin(person, result, request); 
    // then 
      assertEquals("home", validateViewLogin.getViewName()); 


}` 

난 내 단위 테스트를 실행할 때 다음과 같은 오류 얻을 :

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: ModelAndView cannot be returned by validateUserLogin() validateUserLogin() should return boolean


당신이 오류 읽기 위에 얻고있는 이유는 확실하지 않은 경우 에. 위의 구문의 특성상 다음과 같은 이유로 문제가 발생할 수 있습니다. 1.이 예외 일 수 있습니다. 잘못 작성된 다중 스레드 테스트에서 발생합니다. 동시성 테스트의 한계에 대한 Mockito FAQ를 참조하십시오. 2. spy는 when (spy.foo()). then() 구문을 사용하여 스텁됩니다. doReturn | Throw() 패밀리 메소드를 사용하여 스파이를 스텁스럽게 작성하는 것이 더 안전합니다 ( ). Mockito.spy() 메소드에 대한 javadocs의 추가 정보.

at com.gemstone.presentation.LogInControllerTest.testValidateOk(LogInControllerTest.java:49) 
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) 

어떻게하면이 문제를 해결할 수 있습니까?

답변

0

나는 BDD 스타일 Mockito에 익숙하지 해요,하지만 난

given(controller.validateViewLogin(person, result, request)).willReturn(mav); 

당신이 주어진 모델을 반환하고 validateViewLogin 메소드가 호출 될 때마다 볼 수있는 컨트롤러를 요구하는 것을 의미 라인 같은데요 지정된 사람, 결과 및 요청. 그러나 컨트롤러는 모의가 아니므로 오류의 원인이 될 수 있습니다. 대신 모의 사용자 관리자 서비스가 어떻게 작동해야하는지에 대한 동작을 지정해야합니다.

UserManagerServiceImpl 클래스의 모의를 생성하는 것에 주목합니다. 그것이 'Impl'로 끝나는 것을 감안할 때 나는 당신이 대신 조롱 할 수있는 correspondng UserManagerService 인터페이스가 있다고 추측합니다. Mocktio는 구체적인 클래스를 조롱 할 수 있지만 인터페이스를 조롱하는 것만 큼 쉽게 할 수는 없습니다. 그러므로 실제로 인터페이스가 있다면 나는 단지 안전하다는 것을 모의 할 것입니다.

너는 ReflectionTestUtils을 사용하여 너의 모의방을 주사하고있다. 이것은 아마도 오류의 원인이 아니지만 그렇게 할 수 있다면 컨트롤러에 공용 설정기를 추가하여 안전하고 간편하게 주입하는 것이 좋습니다.

위의 점을 가지고 가서, 내가 좋아하는 테스트를 작성합니다 다음

@Test public void validateViewLogin_validLogin_returnsHomePage() { 
    MockHttpServletRequest request = new MockHttpServletRequest(); 
    MockHttpServletResponse response = new MockHttpServletResponse(); 

    Person person = new Person(); 
    person.setFirstName("John"); 
    person.setPassword("123"); 

    LogInController controller = new LogInController(); 
    UserManagerService mockUserService = mock(UserManagerService.class); 

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

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

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

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

내가 선

when(mockUserService.validateUserLogin("John", "123")).thenReturn(true);

를 사용하여 모의를 구성한 BDD 구문에 익숙하지 않다 때문에

하지만 나는이

given(mockUserService.validateUserLogin("John", "123")).willReturn(true);

에 해당하는 것으로 가정
+0

고마워 지금은 잘 작동합니다. 요청한대로 변경합니다. 다시 고마워. – user1999453