jeudi 23 janvier 2020

Unit test a private method via a protected method in Java

I've these two methods from my MetadataManagement class which I'd like to unit test:

@Override
protected void doPut(final HttpServletRequest request, final HttpServletResponse response,
    final MetadataResource resource)
    throws IOException {
  ServiceCommon.checkRole(getSubject(request));

  if (resource.getType() != Type.CONTAINER) {
    final String err = "Request not allowed for " + request.getURI();
    throw new ServiceApiException(ServiceApiError.METHOD_NOT_ALLOWED, err);
  }

  final String name = getContainerName(resource);

  final ServiceApiMetadata config = getConfig(request, PATH);

  final StorageLocation storageLocation = getStorageLocation(conf.getStorageLocation());

  if (config.getNotifications() != null) {
    checkMethodSupported(id);
    checkService(id);
  }
}

private ServiceApiMetadata getConfig(final HttpServletRequest request, final String path)
    throws IOException {
  final Schema schema;
  try (final InputStream inStream = this.getClass().getResourceAsStream(path)) {
    final JSONObject origSchema = new JSONObject(new JSONTokener(inStream));
    if (isGoldStar()) {
      origSchema.getJSONObject("properties")
          .getJSONObject("notifications")
          .getJSONObject("properties")
          .getJSONObject("topic")
          .put("pattern", "^[0-9A-Za-z-.]*$");
    }
    schema = SchemaLoader.load(origSchema);
  }

  final ServiceApiMetadata config;
  try (final BufferedReader reader = request.getReader()) {
    final JSONObject json = new JSONObject(new JSONTokener(reader));
    schema.validate(json);
    config = ServiceApiMetadata.read(json);
  } catch (final ValidationException e) {
    _logger.debug(e.getMessage());
    if (e.getLocation().contains("#/properties/notifications")) {
      throw new ServiceApiException(ServiceApiError.MALFORMED_NOTIFICATIONS_ERROR,
          ServiceApiErrorMessage.MALFORMED_JSON);
    } else {
      throw new ServiceApiException(ServiceApiError.MALFORMED_JSON);
    }
  } catch (final JSONException e) {
    _logger.debug(e.getMessage());
    throw new ServiceApiException(ServiceApiError.MALFORMED_JSON);
  }

  return config;
}

As I understand it I can not directly call getConfig in my test because the method is private. I believe using reflection is an option but is not advised. Based on that, any test of getConfig should be done through doPut.

What I'm most interested in checking is if getConfig.isGoldStar is true, the origSchema pattern updates to ^[0-9A-Za-z]*$ and if it is false it remains at ^[0-9A-Za-z-._]*$.

To call doPut in my test I will need HttpServletRequest, HttpServletResponse and MetadataResource objects. I'm not sure how I generate these. HttpServletRequest and HttpServletResponse are from javax.servlet.ServletRequest and MetadataResource comes from within my project. It takes HttpServletRequest and an enum as parameters.

How do I do this test? I think I should be OK once I can call the doPut method but I'm struggling to do that.

Aucun commentaire:

Enregistrer un commentaire