Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧控制器捕捉块中的单元测试代码_Java_Spring_Unit Testing_Junit_Mockito - Fatal编程技术网

Java 弹簧控制器捕捉块中的单元测试代码

Java 弹簧控制器捕捉块中的单元测试代码,java,spring,unit-testing,junit,mockito,Java,Spring,Unit Testing,Junit,Mockito,我有以下结构的控制器: @RequestMapping(value = "${foo.controller.requestMappingUrl.login}", method = RequestMethod.POST) public ResponseMessage<String> loginUser( @RequestParam("username") String username, HttpServletRequest httpServletReq

我有以下结构的控制器:

@RequestMapping(value = "${foo.controller.requestMappingUrl.login}", method = RequestMethod.POST)
    public ResponseMessage<String> loginUser(
            @RequestParam("username") String username, HttpServletRequest httpServletRequest,
            HttpServletResponse httpServletResponse) {

    try {

       return fooService.login(username); // can mock test

    } catch (UserNotFoundException e) {
            //CANNOT MOCK TEST THIS BLOCK
            String errorMsg = LoggerUtil.printStackTrace(e);
            LOG.error("[RequestId: {}] UserNotFoundException: {}, Stack: {}", requestId, e.getMessage(), errorMsg);
            httpServletResponse.setStatus(HttpStatus.NOT_ACCEPTABLE.value());
            statusCode = StatusCode.UserNotFound.value();
            responseMessage.buildResponseMessage(StringUtils.EMPTY, HttpStatus.NOT_ACCEPTABLE, statusCode,
                    messageByLocaleService.getMessageResponse(statusCode, null, locale));
    }
}
和堆栈跟踪

java.lang.Exception:意外异常, 预期 但是在 org.junit.internal.runners.statements.ExpectException.evaluateExpectException.java:28 在 org.junit.internal.runners.statements.RunBefores.evaluateRunBefores.java:26 在 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluateRunBeforeTestMethodCallbacks.java:75 在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.EvaluaterUnterTestMethodCallbacks.java:86 在 org.springframework.test.context.junit4.statements.SpringRepeat.evaluateSpringRepeat.java:84 位于org.junit.runners.ParentRunner.runLeafParentRunner.java:325处 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChildSpringJUnit4ClassRunner.java:252 在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChildSpringJUnit4ClassRunner.java:94 位于org.junit.runners.ParentRunner$3.runParentRunner.java:290处 org.junit.runners.ParentRunner$1.scheduleParentRunner.java:71 at org.junit.runners.ParentRunner.runChildrenParentRunner.java:288 at org.junit.runners.ParentRunner.access$000ParentRunner.java:58 org.junit.runners.ParentRunner$2.evaluateParentRunner.java:268 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluaterUnbeforetClassCallbacks.java:61 在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.EvaluaterUnterTestClassCallbacks.java:70 位于org.junit.runners.ParentRunner.runParentRunner.java:363 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runSpringJUnit4ClassRunner.java:191 在 org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.runJUnit4TestReference.java:50 在 org.eclipse.jdt.internal.junit.runner.TestExecution.runTestExecution.java:38 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTestsRemoteTestRunner.java:467 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTestsRemoteTestRunner.java:683 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runRemoteTestRunner.java:390 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.mainRemoteTestRunner.java:197 原因:org.springframework.web.util.NestedServletException: 请求处理失败;嵌套异常是 com.atlassian.crowd.exception.runtime.UserNotFoundException位于 org.springframework.web.servlet.FrameworkServlet.processRequestFrameworkServlet.java:982 在 org.springframework.web.servlet.FrameworkServlet.doPostFrameworkServlet.java:872 在javax.servlet.http.HttpServlet.serviceHttpServlet.java:648 at org.springframework.web.servlet.FrameworkServlet.serviceFrameworkServlet.java:846 在 org.springframework.test.web.servlet.TestDispatcherServlet.serviceTestDispatcherServlet.java:65 在javax.servlet.http.HttpServlet.serviceHttpServlet.java:729 at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilterMockFilterChain.java:167 在 org.springframework.mock.web.MockFilterChain.doFilterMockFilterChain.java:134 在 org.springframework.test.web.servlet.MockMvc.performMockMvc.java:155 在 id.co.allianz.microservice.cop.app.auth.controller.AuthControllerTest.TestControllerUserNotFoundExceptionOnAuthControllerTest.java:105 在sun.reflect.NativeMethodAccessorImpl.invoke0Native方法在 sun.reflect.NativeMethodAccessorImpl.invokeNativeMethodAccessorImpl.java:62 在 sun.reflect.DelegatingMethodAccessorImpl.invokeDelegatingMethodAccessorImpl.java:43 java:498 at org.junit.runners.model.FrameworkMethod$1.runReflectVeCallFrameworkMethod.java:50 在 org.junit.internal.runners.model.ReflectiveCallable.runReflectiveCallable.java:12 在 org.junit.runners.model.FrameworkMethod.invokeeexplosivelyframeworkmethod.java:47 在 org.junit.internal.runners.statements.InvokeMethod.evaluateInvokeMethod.java:17 在 org.junit.internal.runners.statements.ExpectException.evaluateExpectException.java:19 ... 22多宗由以下原因引起: com.atlassian.crowd.exception.runtime.UserNotFoundException

您不能期望控制器方法中出现UserNotFoundException异常,因为您只是通过记录并返回带有ERRORCODE144的响应来抑制它

这里的最佳实践是配置ControllerAdvice,以便可以全局处理所有异常,并且您的控制器看起来干净,如下所示。我建议您也查看spring控制器异常处理

例外情况ControllerAdvice类:

您不能期望控制器方法中出现UserNotFoundException异常,因为您只是通过记录并返回带有ERRORCODE144的响应来抑制它

我认为这里的最佳实践是 要配置ControllerAdvice,以便可以全局处理所有异常,并且您的控制器看起来干净,如下图所示,我建议您也查看spring控制器异常处理

例外情况ControllerAdvice类:


你能发布fooService.login的内容吗?对不起,cmmiiw,既然我在模拟服务层,为什么你需要服务层代码呢。服务层函数使用Atlassian crowd并抛出从群组api返回的UserNotFoundException。请发布您得到的NestedServletException的测试代码和堆栈跟踪。@nanospeck然后发布您对该功能的模拟代码使用模拟和堆栈跟踪更新问题您可以发布fooService.login?对不起,cmmiiw,既然我在模仿服务层,为什么你需要服务层代码呢。服务层函数使用Atlassian crowd并抛出从群组api返回的UserNotFoundException。请发布您得到的NestedServletException的测试代码和stacktrace。@nanospeck然后发布您模拟此功能的代码使用mocking和stack tracehey更新问题,听起来是个不错的选择。但是我如何处理编译器警告,在控制器类中用try/catch块包围服务方法。不要在控制器中捕获它,而是在控制器方法签名中添加throws子句,这样ControllerAdvice就会小心了!糟糕的是,我在测试类中模拟了名称重复的错误异常,调用了“import com.atlassian.crowd.Exception.runtime.UserNotFoundException”而不是“import com.atlassian.crowd.Exception.UserNotFoundException”。接受这个答案是因为我发现这种优雅的实现方式有助于尽早识别错误,从而避免了我的错误。我在这里写了一个简单的例子:嘿,听起来是个不错的选择。但是我如何处理编译器警告,在控制器类中用try/catch块包围服务方法。不要在控制器中捕获它,而是在控制器方法签名中添加throws子句,这样ControllerAdvice就会小心了!糟糕的是,我在测试类中模拟了名称重复的错误异常,调用了“import com.atlassian.crowd.Exception.runtime.UserNotFoundException”而不是“import com.atlassian.crowd.Exception.UserNotFoundException”。接受这个答案是因为我发现这种优雅的实现方式有助于尽早识别错误,从而避免了我的错误。我在这里写了一个简单的示例:
@SuppressWarnings("unchecked")
@Test(expected = UserNotFoundException.class)
    public void testControllerUserNotFoundException() throws Exception {
        Response resp = new Response();
        resp.setStatusCode(StatusCode.UserNotFoundErrorCode);
        when(fooService.login(any(String.class)).thenThrow(UserNotFoundException.class);

        mockMvc.perform(post("/service-user/1.0/auth/login?&username=test")
                        .contentType(contentType)).andExpect(status().isNotAcceptable())
                .andExpect(jsonPath("$.statusCode", is("ERRORCODE144")));

    }
@ControllerAdvice
public class ExceptionControllerAdvice {

    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUnexpectedException(UnexpectedException 
                     unExpectedExe) {

        //log and send the response back to the client here
    }
}
@RequestMapping(value = "${foo.controller.requestMappingUrl.login}",
                                 method = RequestMethod.POST)
public ResponseMessage<String> loginUser(
            @RequestParam("username") String username,
               HttpServletRequest httpServletRequest,
               HttpServletResponse httpServletResponse) {

       return fooService.login(username);
}
@Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    mockMvc = MockMvcBuilders.standaloneSetup(projectController)
                .setMessageConverters(new MappingJackson2HttpMessageConverter())
                .setControllerAdvice(new ExceptionControllerAdvice()).build();
}


@SuppressWarnings("unchecked")
@Test
    public void testControllerUserNotFoundException() throws Exception {
        Response resp = new Response();
        resp.setStatusCode(StatusCode.UserNotFoundErrorCode);
        when(fooService.login(any(String.class)).
        thenThrow(UserNotFoundException.class);
        mockMvc.perform(post("/service-user/1.0/auth/login?&username=test")
                        .contentType(contentType)).
     andExpect(status().isNotAcceptable())
                .andExpect(jsonPath("$.statusCode", is("ERRORCODE144")));
}