【问题标题】:Mockito: How to make the service call throw exceptionMockito:如何使服务调用抛出异常
【发布时间】:2018-07-02 12:59:19
【问题描述】:

我的班级中有 Hystrix 命令需要测试。我可以模拟除后备之外的所有代码。要执行回退,我需要让我的 hystrix 包装方法抛出超时异常。我不明白该怎么做。有人可以帮我吗?我尝试在测试类上使用@Enablecircuitbreaker 打开电路,但这并没有调用任何Hystrix 异常:(

     @Mock
     private MDMConnectorService service;
     @InjectMocks
     private AIAUtilities aiaUtilities;

     @Test
  public void testFetchCustomerAccountDetailsHystrixTimeoutException() throws Exception {
    try {
      ConfigurationManager.getConfigInstance()
          .setProperty("hystrix.command.AIAClientCommand.circuitBreaker.forceOpen", "true");
      Mockito.when(service.fetchCustomerAccount(any(GetCustomerAccountType.class))).thenReturn(getTestAIARecord());
      GetCustomerAccountResponseType responseType = aiaUtilities
          .fetchCustomerAccountDetails(accountNumber);
      Assert.assertFalse(true);// if the flow came here, the test case has failed
    } catch (Exception ex) {
      if (ex instanceof DataAccessException) {
        assertEquals(Constants.ERRCODE_AIA_QUERY_TIMED_OUT,
            ((DataAccessException) ex).getErrorCode());
      } else {
        throw ex;
      }
    }
    finally {
      ConfigurationManager.getConfigInstance()
          .setProperty("hystrix.command.AIAClientCommand.circuitBreaker.forceOpen", "false");
    }
  }

在这个测试中,被hystrix包裹的命令在

处被调用
    GetCustomerAccountResponseType responseType = aiaUtilities
      .fetchCustomerAccountDetails(accountNumber);

具有hystrix命令和相应回退的AIAUtilities的代码是

    @HystrixCommand(commandKey = "AIAClientCommand", fallbackMethod = "aiaClientCommandFallback")
    public GetCustomerAccountResponseType fetchCustomerAccountDetails(String accountNumber)
        throws DataAccessException {
      GetCustomerAccountResponseType response;

      try {

        if (generalUtil.isObjectEmpty(authHeader)) {
        authHeader = iamUtilities.createAuthHeaderAndRenewOfflineTicket();
      }
      factory = getFactory();
      request = getRequest();
      accountNumberType = getAccountNumberType();
      accountNumberType.setValue(accountNumber);
      request.setCustomerAccountNumber(accountNumberType);
      request.setSourceId(Constants.VAL_QUICKBASE_SOURCE_AIA);
      serviceClass = getServiceClass();
      service = getService();
      provider = getProvider();;
      provider.getRequestContext().put("Authorization", authHeader);
      provider.getRequestContext().replace("SOAPAction", "fetchCustomerAccount");
      provider.getRequestContext().put("Content-Type", "text/xml");

      response = service.fetchCustomerAccount(request);
      } catch (DataAccessException e) {
        throw e;
      }
      catch (Exception e) {
        if(e instanceof HystrixRuntimeException && e.getCause() instanceof TimeoutException) {
          DataAccessException dataAccessException = (DataAccessException) ((HystrixRuntimeException) e)
              .getFallbackException().getCause();
          throw new DataAccessException(dataAccessException.getErrorCode(),
              "Exception in validateLicense.fetchCustomerAccountDetails::" + e.getMessage(),e);
        }
        else
        throw new DataAccessException(Constants.ERRCODE_AIA_EXCEPTION,
            "Exception in validateLicense.fetchCustomerAccountDetails:::" + e.toString(), e);
      }
      return response;
    }

    private GetCustomerAccountResponseType aiaClientCommandFallback(String accountNumber, Throwable e)
        throws DataAccessException {
      logger.error("Inside AIAClientCommandFallback : Error is ::" + e.toString());
      if(e instanceof HystrixTimeoutException)
        throw new DataAccessException(Constants.ERRCODE_AIA_QUERY_TIMED_OUT,
            "Exception in AIAClientCommandFallback::" + e.toString(),e);
      else if(e instanceof DataAccessException)
        throw (DataAccessException)e;
      else
        throw new DataAccessException(Constants.ERRCODE_AIA_EXCEPTION,
          "Inside AIAClientCommandFallback : Error is ::" + e.toString(), e);
    }

【问题讨论】:

    标签: java mocking mockito hystrix


    【解决方案1】:

    不要在模拟的 fetchCustomerAccount 中返回一些东西,而是通过thenThrow 在那里抛出一个异常:

    Mockito.when(service.fetchCustomerAccount(any(GetCustomerAccountType.class))).thenThrow(new RuntimeException("Timeout"));
    

    【讨论】:

    • hystrix封装的调用由GetCustomerAccountResponseType responseType = aiaUtilities .fetchCustomerAccountDetails(accountNumber);
    • 好的,所以你需要模拟aiaUtilities 并在那里抛出异常?如Mockito.when(aiaUtilities .fetchCustomerAccountDetails(..)).thenThrow(...)
    • 但是,测试是针对 aiaUtilities 本身的。
    • 好的...但是如果 aiaUtilities 使用 MDMConnectorService 服务,那么第一个解决方案应该可以工作,不是吗?否则,MDMConnectorService 的嘲讽是为了什么?
    • 我无法让外部服务抛出它们并非旨在抛出的异常。我的代码 aiaUtilities.fetchCustomerAccountDetails 应该抛出异常来调用回退。
    猜你喜欢
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 2019-07-25
    相关资源
    最近更新 更多