0

I want to unit-test a method like this:

public String handleRequest(Event event) {
      for(Message msg : event.getRecords()){
           SDKClient client = new SDKClient(msg.getUser(), msg.getPassword());
           String output = client.makeAPICall();
           return output.toUpperCase();
       }
   }

}

Typically, we mock dependencies like SDKClient by passing them in as arguments and mocking them in Junit/Mockito. However, in this case, I cannot just pass it because the SDKClient depends on the actual events passed in. There is also an undetermined number of clients, one for each message in the event. I want to unit test the method as a whole, but I do not know the dependencies in advance. Is it possible?

db-user
  • 223
  • 1
  • 2
  • 11

1 Answers1

1

In that case, what you pass in is some kind of function that abstracts the new SDKClient call:

interface SdkClientProvider {
    SDKClient(String user, String password);
}

In this particular case, you could use BiFunction<String, String, SDKClient> if you prefer.

As new SDKClient is likely to be the only "live" implementation of this class, you can even do something like this:

class MyService {
    @Setter
    private BiFunction<String, String, SDKClient> createClient = SDKClient::new;

    ...
}

This pattern is commonly seen when depending on the system java.time.Clock.

(Note that the "create, use, and dispose of a service object" is a very questionable design, and unless you're stuck with consuming some badly-designed external library, it's begging for refactoring.)

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152