0

We are integrating into Auth0 API's and as a part this whole mess, we have a function that converts UserInfo (from Auth0 lib) to our own case class.

The signature of this function is:

private[services] def convertUserInfoToAuth0UserInfo(userInfo: UserInfo): Auth0UserInfo

I am trying to create a unit test for this function, and for the setup I need to create UserInfo object and populate it with data.

val profileMap = Map(
          "email" -> "name@email.com",
          "username" -> "username",
          "organizationName" -> "organizationName",
          "avatarUrl" -> "avatarUrl",
          "domains" -> List("domain.com"),
          "access_token" -> "access_token"
      )

      val userInfo = new UserInfo()
      userInfo.setValue("key", profileMap.asJava)

      val auth0UserInfo = service.convertUserInfoToAuth0UserInfo(userInfo)

      auth0UserInfo.accessToken must beSome("access_token")

The issue is setValue function is not accessible for whatever reason, even though the UserInfo class itself looks like this:

package com.auth0.json.auth;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

import java.util.HashMap;
import java.util.Map;

/**
 * Class that holds the Information related to a User's Access Token. Obtained after a call to {@link com.auth0.client.auth.AuthAPI#userInfo(String)},
 * {@link com.auth0.client.auth.AuthAPI#signUp(String, String, String)} or {@link com.auth0.client.auth.AuthAPI#signUp(String, String, String, String)}.
 */
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserInfo {

    private Map<String, Object> values;

    UserInfo() {
        values = new HashMap<>();
    }

    @JsonAnySetter
    void setValue(String key, Object value) {
        values.put(key, value);
    }

    /**
     * Getter for the values contained in this object
     *
     * @return the values contained in the object.
     */
    @JsonAnyGetter
    public Map<String, Object> getValues() {
        return values;
    }
}

Unless I am missing something, setValues is public. Why can't I use it?

Shurik Agulyansky
  • 2,607
  • 2
  • 34
  • 76
  • 1
    I see a package private `void setValue(...)` which means `setValues(...)` wont work both because the method name does not match, and because you are not in the same package as `void setValue(...)`. See [this](https://stackoverflow.com/a/215505/2442526) answer for info about Java access modifiers. – xtratic Jun 14 '18 at 18:49
  • 1
    Instead use: `userInfo.getValues().put("https://app.process.st/", profileMap.asJava)` – xtratic Jun 14 '18 at 18:51
  • Ha ha!!! Apparently, I can't even construct the object for the same reason – Shurik Agulyansky Jun 14 '18 at 18:56
  • Yep, that too. Didn't even look at that one. – xtratic Jun 14 '18 at 18:58
  • That is not very useful, how do we test this thing then? – Shurik Agulyansky Jun 14 '18 at 19:00
  • I'm not exactly sure. How are you getting the `UserInfo` in the service? You might have to feed it in via JSON. – xtratic Jun 14 '18 at 19:16

1 Answers1

1

Even though the class is public, the method, without an access-modifier keyword, is by default:

void setValue(...) \\Package-Private

Since you don't own the package, you cannot UnitTest this way. Besides, that technically enters the realm of integration testing.

The proper way, which can be tedious to get rigorous coverage, would be to set up a mock environment, using either injection or environment variable to control which class gets used.

  • 1
    It isn't protected, it's package-private. If it were protected, that would make it a little easier since UserInfo could simply be subclassed in order to make the method public. In this case, however, the test must make `setValue` accessible and invoke it with reflection. – Lucas Ross Jun 14 '18 at 19:49
  • @LucasRoss, you are correct, it's a Java Package, thus no access modifier means package-private. I've updated my answer. Thanks! – Randomness Slayer Jun 14 '18 at 21:05