package com.messagebird; import com.messagebird.exceptions.GeneralException; import java.util.HashMap; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; /** * Builder for effortlessly constructing spy services of MessageBirdServiceImpl. *
* The following example configures a mock to return an OK response with a * response of your choice whenever doRequest() is called: * *
* MessageBirdService messageBirdService = SpyService
* .expects("GET", "conversatons/convid")
* .withConversationsAPIBaseURL()
* .andReturns(new ApiResponse("YOUR_RESPONSE_BODY"));
*
*
* @param Type of the payload being (optionally) returned. */ class SpyService
{ private static final String CONVERSATIONS_API_BASE_URL = "https://conversations.messagebird.com/v1"; private static final String REST_API_BASE_URL = "https://rest.messagebird.com"; private static final String VOICE_CALLS_BASE_URL = "https://voice.messagebird.com"; private String method; private String url; private P payload; private String baseURL; SpyService() { // } /** * Gets the access key for the MessageBirdService. Can be overridden, but * if a use case requires this, the mock is likely not used properly. *
* It is strongly advisable to NOT make this a valid access key for several * reasons, but also because Mockito uses loose mocks. This means that if a * mocked method is invoked without any matching expectations (for example, * with the wrong parameters), it does not throw exceptions. It instead * calls the real implementation. Leaving the access key blank ensures an * exception is thrown ("not authorized"), causing the test to fail. * * @return Access key for MessageBirdService. */ protected String getAccessKey() { return ""; } /** * Sets up a spy and configures its expectations for doRequest(). * * @param method Method that doRequest() expects. * @param url URL that doRequest() expects. * @param payload Payload that doRequest() expects. * @param
Type of the payload. * @return Intermediate SpyService that can be finalized through * andReturns(). */ static
SpyService expects(final String method, final String url, final P payload) { SpyService service = new SpyService
(); service.method = method; service.url = url; service.payload = payload; return service; } /** * Sets up a spy and configures its expectations for doRequest(). This sets * the expected payload to null - useful for requests without bodies, like * GETs and DELETEs. To provide an expected payload, use the overload. * * @param method Method that doRequest() expects. * @param url URL that doRequest() expects. * @return Intermediate SpyService that can be finalized through * andReturns(). */ static SpyService expects(final String method, final String url) { return SpyService.expects(method, url, null); } /** * Sets a base URL to prefix the URL provided to expects() with when * building the spy. * * @param baseURL String to prefix the URL with when building the spy. * @return Intermediate SpyService that can be finalized through * andReturns(). */ SpyService withBaseURL(final String baseURL) { this.baseURL = baseURL; return this; } /** * Sets the base URL to match the Conversations API's. * * @return Intermediate SpyService that can be finalized through * andReturns(). */ SpyService withConversationsAPIBaseURL() { return withBaseURL(CONVERSATIONS_API_BASE_URL); } /** * Prefixes all URLs provided to expects() with the REST API's base URL * when building the spy. * * @return Intermediate SpyService that can be finalized through * andReturns(). */ SpyService withRestAPIBaseURL() { return withBaseURL(REST_API_BASE_URL); } /** * Sets the base URL to match the Voice Call API's. * * @return Intermediate SpyService that can be finalized through * andReturns(). */ SpyService withVoiceCallAPIBaseURL() { return withBaseURL(VOICE_CALLS_BASE_URL); } /** * Finalizes the SpyService by configuring its return value for * doRequest() and builds the spy. * * @param apiResponse APIResponse to return from the spy when doRequest() * is invoked with the configured expectation. * @return MessageBirdServiceImpl with a spy on doRequest(). * @throws GeneralException */ MessageBirdService andReturns(final APIResponse apiResponse) throws GeneralException { if (baseURL != null && !baseURL.isEmpty()) { url = String.format("%s/%s", baseURL, url); } MessageBirdServiceImpl messageBirdService = spy(new MessageBirdServiceImpl(getAccessKey())); doReturn(apiResponse).when(messageBirdService).doRequest(method, url, new HashMap<>(), payload); return messageBirdService; } }