Java 单元测试 - 未抛出异常

Java unit test - exception not being thrown

尝试编写一个将调用我的方法的测试,当该方法调用另一个方法时,我们将抛出我创建的自定义异常。在这里我把它都简化了

2 个函数

public MyJsonResponse hello() {
        MyJsonResponse response = new MyJsonResponse();
        response.setErrorMessage("1");
        response.setStatus("some status");
        response.setData("1");
        response.setHttpResponse(200);
        try{
            hi();
            return response;
        }catch (MyServiceException e) {
            response.setErrorMessage(e.getMessage());
            response.setStatus("error creating");
            response.setData("2");
            response.setHttpResponse(e.getResponseStatus());
            return response;
        }

    }

    public String hi() throws  MyServiceException{
        LOG.error("Exception");
        return "yea";
    }

我写的测试是这样的

    @Test
    public void myTest() throws Exception {

        given(service.hi()).willAnswer( invocation -> { throw new MyServiceException("abc msg",511); });
        MyJsonResponse actual = service.hello();

        Assert.assertNotNull(actual);
        assertEquals(511, actual.getHttpResponse());
    }

可惜结果如下

java.lang.AssertionError: 
Expected :511
Actual   :200

为了使此测试有意义,您的 hi() 调用应该调用您在测试 class 中 stub/mock 的另一个服务。你没有那样做,所以这个方法行不通。

你写了“hi 代表的真正方法做了很多”,所以是时候将它提取到另一个服务了。

关于你的解释和你的代码是什么样的,我不确定我是否理解了。 因此,如果您需要,您的 hi() : 函数会抛出异常。 你必须先让它抛出异常。看看下面的代码!

 public String hi() throws  MyServiceException{
        /*LOG.error("Exception");//No don't just log, throw a real exception as below*/
       throw new MyServiceException("text here, if your constructor support it or nothing otherwise")
     /*return "yea";//Nothing to return? we have just break the code by throwing the exception above*/
    }

之后,请非常确定你的'MyServiceException.getHttpResponse()'真的会return511

请确保您使用的是关于该主题的spy as you want to use the actual code for some methods of your mocked service and just stubbing specific methods of it. Please, see for instance this related SO question

此外,考虑修改您的测试定义以使用 willThrow 而不是 willAnswer:正如@eis 所指出的,您仍然可以使用后者,但前者更直接。

您的代码将类似于:

@Test
public void myTest() throws Exception {
  MyService service = spy(MyService.class);

  willThrow(new MyServiceException("abc msg",511))
    .given(service)
    .hi()
  ;

  // As pointed out by @eis, you can still use willAnswer
  // willAnswer(
  //   invocation -> { throw new MyServiceException("abc msg",511);}
  // )
  //   .given(service)
  //   .hi()
  // ;

  
  MyJsonResponse actual = service.hello();

  Assert.assertNotNull(actual);
  assertEquals(511, actual.getHttpResponse());
}