Michal Michal - 24 days ago 12
Java Question

Java optional parameter in argument for similiar methods

In below two methods I would like to extract common methods, the problem I have is that aisleID in one of it is optional - is it any way to put optional argument in java method ?

private void putPageUnderAisleId(String aisleId) {
given()
.spec(prepareApplicationJsonHeaders())
.header(HttpHeaders.AUTHORIZATION, verifiableToken(Roles.WRITE_MERCHANDISING))
.body(readResource(NAMED_PAGE_CONTENT_FILE, String.format("%s.html", TEST_PAGE.value()), AISLE_TEST_LOCATION))
.put(AISLE_HTML_URL, aisleId)
.then()
.statusCode(200)
.body(not(isEmptyOrNullString()))
.body(JSON_RESPONSE_MESSAGE, not(isEmptyOrNullString()));
}

private void putPageUnderRootAisleId() {
given()
.spec(prepareApplicationJsonHeaders())
.header(HttpHeaders.AUTHORIZATION, verifiableToken(Roles.WRITE_MERCHANDISING))
.body(readResource(NAMED_PAGE_CONTENT_FILE, String.format("%s.html", TEST_PAGE.value()), AISLE_TEST_LOCATION))
.put(ROOT_AISLE_HTML_URL)
.then()
.statusCode(200)
.body(not(isEmptyOrNullString()))
.body(JSON_RESPONSE_MESSAGE, not(isEmptyOrNullString()));
}

Answer

Why not something like this?

private void putPageUnderRootAisleId() {
    return putPageUnderAisleId(null);
}

private void putPageUnderAisleId(String aisleId) {
    Object putKey = aisleId != null ? AISLE_HTML_URL : ROOT_AISLE_HTML_URL;
    given()
            .spec(prepareApplicationJsonHeaders())
            .header(HttpHeaders.AUTHORIZATION, verifiableToken(Roles.WRITE_MERCHANDISING))
            .body(readResource(NAMED_PAGE_CONTENT_FILE, String.format("%s.html", TEST_PAGE.value()), AISLE_TEST_LOCATION))
            .put(putKey, aisleId)
            .then()
            .statusCode(200)
            .body(not(isEmptyOrNullString()))
            .body(JSON_RESPONSE_MESSAGE, not(isEmptyOrNullString()));
}

The good part on this approach is that you only have to maintain one method. I defined the putKey as Object because I don't know wich library are you using. The only different part between both methods is the put() part. Just check the put method implementation. 99% sure the one with 1 argument calls the one with 2 providing as the second one a default value. If this default argument is null you are ready to go with mine. If it differs from null, then you only have to do an assignation like this to aisleId:

aisleId != null ? aisleId : %defaultValue;

being %defaultValue the default value the method put is using on the one argument implementation.

As pointed by @AxelH, if put receives varargs, the approach above is risky (and probably not correct), so in that case you should create an Object[] to provide these arguments:

private void putPageUnderRootAisleId() {
    return putPageUnderAisleId(null);
}

private void putPageUnderAisleId(String aisleId) {
    Object putKey = aisleId != null ? AISLE_HTML_URL : ROOT_AISLE_HTML_URL;
    Object[] putArgs = aisleId != null ? new Object[]{aisleId} : new Object[]{};

    given()
            .spec(prepareApplicationJsonHeaders())
            .header(HttpHeaders.AUTHORIZATION, verifiableToken(Roles.WRITE_MERCHANDISING))
            .body(readResource(NAMED_PAGE_CONTENT_FILE, String.format("%s.html", TEST_PAGE.value()), AISLE_TEST_LOCATION))
            .put(putKey, putArgs)
            .then()
            .statusCode(200)
            .body(not(isEmptyOrNullString()))
            .body(JSON_RESPONSE_MESSAGE, not(isEmptyOrNullString()));
}