function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ankita LAnkita L 

I achieved 40% code coverage need to achieve more.

Hi everyone,
my i am stuck in test class need my code coverage is not improving.
Can u please help to to achive. 
my apex code:
public class MindbodySubscriberService
{
    //when testing in dev you need to generate a new token via postman and put it in the devToken variable below. auth.mbodev.me is NOT available from salesforce!
    static final String devToken = null; //auth.mbodev.me is not available externally this should be generated via postman and put here for testing
    static final String authUser = 'SfEventClientUser'; //in dev/sanbox we have to fake the auth using the devToken above so these values are for production
    static final String authPass = 'dTr58@1GvUlob!';
    static String authToken = null;
    static datetime authExpiry = datetime.now().addMinutes(-10);
    
    @future(callout=true)
    public static void sendNotification(String oldEmail, String newEmail, String AccountNumber) 
    {
        System.debug('MBSubscriberService.sendNotification ' + AccountNumber);
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();
        string token = MindbodyAuthCallout();
        if (token == null)
        {
            System.debug('Failed to authenticate to Mindbody');
            return;
        }
        req.setHeader('Authorization','Bearer ' + token);
        req.setEndpoint(SubscriberUrl());
        req.setMethod('PUT');
        req.setHeader('Content-Type', 'application/json');
        
        EmailAccountObject upData = new EmailAccountObject();
        upData.OldEmail = oldEmail;
        upData.NewEmail = newEmail;
        upData.AccountNumber = AccountNumber;
        req.setBody(JSON.serialize(upData));
        System.debug(upData);
        try 
        {
            res = http.send(req);
            System.debug(res.getBody());
            System.debug(res.getStatus());
        } 
        catch(System.CalloutException e) 
        {
            System.debug('MB Callout error: '+ e);
            System.debug(res.toString());
        }
    }

public static string MindbodyAuthCallout ()
{
    if(Test.isRunningTest()){
         return null;   
    }
     if (isSandbox())
     {
        MindbodySubscriberService.authExpiry = datetime.now().addSeconds(7000); //just assume it's valid for dev environments 
        return MindbodySubscriberService.devToken;
     }
     if (MindbodySubscriberService.authToken != null && MindbodySubscriberService.authExpiry > datetime.now().addMinutes(-5))
     {
        return MindbodySubscriberService.authToken;
     }
     MBAuthObject auth = new MBAuthObject();
     auth.username = MindbodySubscriberService.authUser;
     auth.password = MindbodySubscriberService.authPass;
     auth.grant_type = 'password';
     auth.scope = 'urn:mboframeworkapi';
     HttpRequest req = new HttpRequest();
     req.setEndpoint('https://auth.mindbodyonline.com/issue/oauth2/token');
     req.setMethod('POST');
     req.setHeader('Authorization', 'Basic U2ZFdmVudENsaWVudDppaEF5bm9hR2xaZko4dzFieU9yU3pCZ3doUjR1cURLaTUvdE9LYlgyc1FBPQ==');
     req.setHeader('Content-Type', 'application/json');
     req.setBody(JSON.serialize(auth));
   
     // Create a new http object to send the request object
     // A response object is generated as a result of the request  
  
     Http http = new Http();
     HttpResponse res = http.send(req);

     JSONParser parser = JSON.createParser(res.getBody());
     while (parser.nextToken() != null) 
     {
        if (parser.getCurrentToken() == JSONToken.FIELD_NAME)
        {
            if (parser.getText() == 'access_token')
            {
                        parser.nextToken();
                        MindbodySubscriberService.authToken = parser.getText();
            }
            if (parser.getText() == 'expires_in')
            {
                        parser.nextToken();
                        MindbodySubscriberService.authExpiry = datetime.now().addSeconds(parser.getIntegerValue());
            }
        }
        if (MindbodySubscriberService.authExpiry > datetime.now())
        {
            return MindbodySubscriberService.authToken;
        }
     }
     System.debug ('Failed to get response token:' + res.getBody());
     return null;
}

public class MBAuthObject
{
    public String username;
    public String password;
    public String grant_type;
    public String scope;
}

public class EmailAccountObject
{
    public string AccountNumber;
    public string OldEmail;
    public string NewEmail;
}

  // Updates Subscriber Information in MINDBODY SAAS subscriber database as needed for the principal owner
  // Reach out to MB PT & E before modifying or disabling this trigger.  Primary use is STRIPE payout notifications
  // Author: A.J. Brann June 2018

  public static void UpdateMindbodySubscriberWhenPrincipalOwner(List<Contact> listContacts, Map<Id, Contact> oldMap, Boolean isInsert, Boolean isUpdate)
  {
      /*
    if(Test.isRunningTest())  //too many test failures in production, mocking the auth doesn't seem to help so we're just going to jump ship and not do anything from a test.
    {
           return;
    }
*/
    for(contact c: listContacts)
    {
        String contact_account;
        /*Update SAAS Platform for payout notifications to the principal owner upon change of email*/
        if(c.Role__c == 'Principal Owner' && isUpdate  && c.Email != oldMap.get(c.ID).Email)
        {
            //retrieve the account for this contact
            List<Account> contact_accounts = [select MINDBODY_ID__c from Account where Id =: c.AccountId];
            if(!contact_accounts.isEmpty())
            {
                contact_account = contact_accounts[0].MINDBODY_ID__c;
                //post it to MINDBODY SAAS platform subscriber webhook
                sendNotification(oldMap.get(c.ID).Email, c.Email, contact_account);
            }

        }
        if (c.Role__c != 'Principal Owner' && isUpdate && oldMap.get(c.ID).Role__c == 'Principal Owner') //role changed from principal owner
        {
            //retrieve the account for this contact
            List<Account> contact_accounts = [select MINDBODY_ID__c from Account where Id =: c.AccountId];
            if(!contact_accounts.isEmpty())
            {
                contact_account = contact_accounts[0].MINDBODY_ID__c;
                //post it to MINDBODY SAAS platform subscriber webhook
                sendNotification(oldMap.get(c.ID).Email, '', contact_account);
            }
        }
        if (c.Role__c == 'Principal Owner' && isInsert) //possible new owner
        {
            //retrieve the account for this contact
            List<Account> contact_accounts = [select MINDBODY_ID__c from Account where Id =: c.AccountId];
            if(!contact_accounts.isEmpty())
            {
                contact_account = contact_accounts[0].MINDBODY_ID__c;
                //post it to MINDBODY SAAS platform subscriber webhook
                sendNotification('', c.Email, contact_account);
            }
        }
    }
  }
  
 @testVisible
    private Static Boolean isSandbox(){
        String host = URL.getSalesforceBaseUrl().getHost();
        String server = host.substring(0,host.indexOf('.'));
 
        // It's easiest to check for 'my domain' sandboxes first 
        // even though that will be rare
        if(server.contains('--'))
            return true;
 
        // tapp0 is a unique "non-cs" server so we check it now
        if(server == 'tapp0')
            return true;
 
        // If server is 'cs' followed by a number it's a sandbox
        if(server.length()>2){
            if(server.substring(0,2)=='cs'){
                try{
                    Integer.valueOf(server.substring(2,server.length()));
                }
                catch(exception e){
                    //started with cs, but not followed by a number
                    return false;
                }
 
                //cs followed by a number, that's a hit
                return true;
            }
        }
        // If we made it here it's a production box
        return false;
    }
@TestVisible
    private Static String SubscriberUrl ()
    {
        String devSubscriber = 'https://subscriber.mbodev.me/Subscriber/Settings';
        String prodSubscriber = 'https://subscriber.mindbodyonline.com/Subscriber/Settings';
        if (isSandbox())
        {
            return devSubscriber;
        } 
        return prodSubscriber;
    }
 }

================================
my test class
=================================
public class MindbodySubscriberService
{
    //when testing in dev you need to generate a new token via postman and put it in the devToken variable below. auth.mbodev.me is NOT available from salesforce!
    static final String devToken = null; //auth.mbodev.me is not available externally this should be generated via postman and put here for testing
    static final String authUser = 'SfEventClientUser'; //in dev/sanbox we have to fake the auth using the devToken above so these values are for production
    static final String authPass = 'dTr58@1GvUlob!';
    static String authToken = null;
    static datetime authExpiry = datetime.now().addMinutes(-10);
    
    @future(callout=true)
    public static void sendNotification(String oldEmail, String newEmail, String AccountNumber) 
    {
        System.debug('MBSubscriberService.sendNotification ' + AccountNumber);
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();
        string token = MindbodyAuthCallout();
        if (token == null)
        {
            System.debug('Failed to authenticate to Mindbody');
            return;
        }
        req.setHeader('Authorization','Bearer ' + token);
        req.setEndpoint(SubscriberUrl());
        req.setMethod('PUT');
        req.setHeader('Content-Type', 'application/json');
        
        EmailAccountObject upData = new EmailAccountObject();
        upData.OldEmail = oldEmail;
        upData.NewEmail = newEmail;
        upData.AccountNumber = AccountNumber;
        req.setBody(JSON.serialize(upData));
        System.debug(upData);
        try 
        {
            res = http.send(req);
            System.debug(res.getBody());
            System.debug(res.getStatus());
        } 
        catch(System.CalloutException e) 
        {
            System.debug('MB Callout error: '+ e);
            System.debug(res.toString());
        }
    }

public static string MindbodyAuthCallout ()
{
    if(Test.isRunningTest()){
         return null;   
    }
     if (isSandbox())
     {
        MindbodySubscriberService.authExpiry = datetime.now().addSeconds(7000); //just assume it's valid for dev environments 
        return MindbodySubscriberService.devToken;
     }
     if (MindbodySubscriberService.authToken != null && MindbodySubscriberService.authExpiry > datetime.now().addMinutes(-5))
     {
        return MindbodySubscriberService.authToken;
     }
     MBAuthObject auth = new MBAuthObject();
     auth.username = MindbodySubscriberService.authUser;
     auth.password = MindbodySubscriberService.authPass;
     auth.grant_type = 'password';
     auth.scope = 'urn:mboframeworkapi';
     HttpRequest req = new HttpRequest();
     req.setEndpoint('https://auth.mindbodyonline.com/issue/oauth2/token');
     req.setMethod('POST');
     req.setHeader('Authorization', 'Basic U2ZFdmVudENsaWVudDppaEF5bm9hR2xaZko4dzFieU9yU3pCZ3doUjR1cURLaTUvdE9LYlgyc1FBPQ==');
     req.setHeader('Content-Type', 'application/json');
     req.setBody(JSON.serialize(auth));
   
     // Create a new http object to send the request object
     // A response object is generated as a result of the request  
  
     Http http = new Http();
     HttpResponse res = http.send(req);

     JSONParser parser = JSON.createParser(res.getBody());
     while (parser.nextToken() != null) 
     {
        if (parser.getCurrentToken() == JSONToken.FIELD_NAME)
        {
            if (parser.getText() == 'access_token')
            {
                        parser.nextToken();
                        MindbodySubscriberService.authToken = parser.getText();
            }
            if (parser.getText() == 'expires_in')
            {
                        parser.nextToken();
                        MindbodySubscriberService.authExpiry = datetime.now().addSeconds(parser.getIntegerValue());
            }
        }
        if (MindbodySubscriberService.authExpiry > datetime.now())
        {
            return MindbodySubscriberService.authToken;
        }
     }
     System.debug ('Failed to get response token:' + res.getBody());
     return null;
}

public class MBAuthObject
{
    public String username;
    public String password;
    public String grant_type;
    public String scope;
}

public class EmailAccountObject
{
    public string AccountNumber;
    public string OldEmail;
    public string NewEmail;
}

  // Updates Subscriber Information in MINDBODY SAAS subscriber database as needed for the principal owner
  // Reach out to MB PT & E before modifying or disabling this trigger.  Primary use is STRIPE payout notifications
  // Author: A.J. Brann June 2018

  public static void UpdateMindbodySubscriberWhenPrincipalOwner(List<Contact> listContacts, Map<Id, Contact> oldMap, Boolean isInsert, Boolean isUpdate)
  {
      /*
    if(Test.isRunningTest())  //too many test failures in production, mocking the auth doesn't seem to help so we're just going to jump ship and not do anything from a test.
    {
           return;
    }
*/
    for(contact c: listContacts)
    {
        String contact_account;
        /*Update SAAS Platform for payout notifications to the principal owner upon change of email*/
        if(c.Role__c == 'Principal Owner' && isUpdate  && c.Email != oldMap.get(c.ID).Email)
        {
            //retrieve the account for this contact
            List<Account> contact_accounts = [select MINDBODY_ID__c from Account where Id =: c.AccountId];
            if(!contact_accounts.isEmpty())
            {
                contact_account = contact_accounts[0].MINDBODY_ID__c;
                //post it to MINDBODY SAAS platform subscriber webhook
                sendNotification(oldMap.get(c.ID).Email, c.Email, contact_account);
            }

        }
        if (c.Role__c != 'Principal Owner' && isUpdate && oldMap.get(c.ID).Role__c == 'Principal Owner') //role changed from principal owner
        {
            //retrieve the account for this contact
            List<Account> contact_accounts = [select MINDBODY_ID__c from Account where Id =: c.AccountId];
            if(!contact_accounts.isEmpty())
            {
                contact_account = contact_accounts[0].MINDBODY_ID__c;
                //post it to MINDBODY SAAS platform subscriber webhook
                sendNotification(oldMap.get(c.ID).Email, '', contact_account);
            }
        }
        if (c.Role__c == 'Principal Owner' && isInsert) //possible new owner
        {
            //retrieve the account for this contact
            List<Account> contact_accounts = [select MINDBODY_ID__c from Account where Id =: c.AccountId];
            if(!contact_accounts.isEmpty())
            {
                contact_account = contact_accounts[0].MINDBODY_ID__c;
                //post it to MINDBODY SAAS platform subscriber webhook
                sendNotification('', c.Email, contact_account);
            }
        }
    }
  }
  
 @testVisible
    private Static Boolean isSandbox(){
        String host = URL.getSalesforceBaseUrl().getHost();
        String server = host.substring(0,host.indexOf('.'));
 
        // It's easiest to check for 'my domain' sandboxes first 
        // even though that will be rare
        if(server.contains('--'))
            return true;
 
        // tapp0 is a unique "non-cs" server so we check it now
        if(server == 'tapp0')
            return true;
 
        // If server is 'cs' followed by a number it's a sandbox
        if(server.length()>2){
            if(server.substring(0,2)=='cs'){
                try{
                    Integer.valueOf(server.substring(2,server.length()));
                }
                catch(exception e){
                    //started with cs, but not followed by a number
                    return false;
                }
 
                //cs followed by a number, that's a hit
                return true;
            }
        }
        // If we made it here it's a production box
        return false;
    }
@TestVisible
    private Static String SubscriberUrl ()
    {
        String devSubscriber = 'https://subscriber.mbodev.me/Subscriber/Settings';
        String prodSubscriber = 'https://subscriber.mindbodyonline.com/Subscriber/Settings';
        if (isSandbox())
        {
            return devSubscriber;
        } 
        return prodSubscriber;
    }
 }
Best Answer chosen by Ankita L
Tad Aalgaard 3Tad Aalgaard 3
MindbodySubscriberService is not a test class.  I see nothing in your code above that is a test class or method.  How were you able to acheive 40%?  I'm guessing that there are other test classes that are giving you the 40%. 

I would suggest you take some Trailhead courses to learn how to create test classes and methods.  The training in these modules is very good and should help you get a basis on how to start writing a test class for your code.

https://trailhead.salesforce.com/en/content/learn/modules/apex_testing/apex_testing_intro