Skip to content

Instantly share code, notes, and snippets.

@douglascayers
Last active January 7, 2021 05:23
Embed
What would you like to do?
Apex test classes for the BitlyService. The .java extension is just for syntax highlighting, save them as .cls in your project.
@IsTest
public class BitlyHttpCalloutMock implements HttpCalloutMock {
public HttpResponse respond(HttpRequest req) {
String endpoint = req.getEndpoint();
if ( endpoint.contains('/oauth/access_token') ) {
return buildOAuthResponse( req );
} else if ( endpoint.contains('/v4/shorten') ) {
return buildShortenResponse( req );
}
return null;
}
private HttpResponse buildOAuthResponse(HttpRequest req) {
HttpResponse res = new HttpResponse();
res.setBody('123');
res.setStatusCode(200);
return res;
}
private HttpResponse buildShortenResponse(HttpRequest req) {
HttpResponse res = new HttpResponse();
// See https://dev.bitly.com/api-reference#createBitlink
// for full details of what a response could include.
res.setBody(JSON.serializePretty(new Map<String, Object>{
'link' => 'https://sforce.co/3rUWGZ8'
}));
res.setStatusCode(200);
return res;
}
}
@IsTest
private class BitlyServiceTest {
@IsTest
static void test_shorten() {
Test.startTest();
Test.setMock(HttpCalloutMock.class, new BitlyHttpCalloutMock());
BitlyService service = new BitlyService();
String longURL = 'https://this-is-a-test.example.com';
String shortURL = service.shorten(longURL);
Test.stopTest();
System.assertEquals('https://sforce.co/3rUWGZ8', shortURL);
}
}
@IsTest
private class BitlyShortenURLInvocableTest {
@IsTest
static void test_shorten() {
// If there is an active process on Case object that invokes the
// BitlyShortenURLInvocable as outlined in my blog post
// https://douglascayers.wordpress.com/2015/10/21/salesforce-create-short-urls-with-bitly-process-builder-and-apex/
// then simply inserting the record will cause the code to run and ensure code coverage.
// Otherwise, the other test method is sufficient.
Test.startTest();
Test.setMock(HttpCalloutMock.class, new BitlyHttpCalloutMock());
Case caseObj = new Case();
insert caseObj;
Test.stopTest();
caseObj = [ SELECT Id, Short_URL__c FROM Case WHERE Id = :caseObj.Id LIMIT 1 ];
System.assert( String.isNotBlank( caseObj.Short_URL__c ) );
}
@IsTest
static void test_shorten2() {
// This test just ensures the invocable class will run.
// If we were to have an active process or trigger then
// inserting the record would be sufficient, as in the above test method.
// If not, then this method will be sufficient for code coverage.
//
// However, do note that trying to do both in the same test will fail.
// Trying to insert a record and call the invocable class will fail
// because the invocable class calls a @Future method that makes an HttpCallout.
// DML operations don't mix with HttpCallouts due to uncommitted work:
// "System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out.""
Test.startTest();
Test.setMock(HttpCalloutMock.class, new BitlyHttpCalloutMock());
BitlyShortenURLInvocable.shorten( new String[] {} );
Test.stopTest();
}
}
@douglascayers
Copy link
Author

Companion apex test classes for the BitlyService I blogged about here: https://douglascayers.wordpress.com/2015/10/21/salesforce-create-short-urls-with-bitly-process-builder-and-apex/

Gist to the BitlyService is here: https://gist.github.com/DouglasCAyers/edd79ebe9114068b3f5a
Gist to the BitlyShortenURLInvocable is here: https://gist.github.com/DouglasCAyers/fc8b704f2558d37dc47a

@aschattopadhyay
Copy link

Hi Douglas:

Thanks for this awesome piece of code. I could make my bitly thing working, using a process builder. My bitly field is on Opportunity. However my test method fails in static void test_shorten() in BitlyShortenURLInvocableTest . It throws the following error:

System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
Class.BitlyService.getAccessToken: line 56, column 1
Class.BitlyService.: line 12, column 1
Class.ShortURLInvoc.shortenAsync: line 25, column 1

My code in test_shorten is given below.

    Test.startTest();
    Test.setMock( HttpCalloutMock.class, new MockHttpResponse() );
    
    Opportunity job = new Opportunity();
    job.Name = 'Test Job';
    job.StageName = 'Not yet started';
    job.CloseDate = System.today() ; 
    insert job;
    Test.stopTest();
      
      
    job  = [ SELECT id, Shortened_Url__c FROM Opportunity WHERE id = :job.id LIMIT 1 ];
    
    System.assert( String.isNotBlank( job.Shortened_Url__c ) );

@douglascayers
Copy link
Author

Code updated to use Bitly's API v4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment