Skip to content

Instantly share code, notes, and snippets.

@douglascayers
Last active January 7, 2021 05:23
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save douglascayers/de978590b97e235a96fc to your computer and use it in GitHub Desktop.
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