Search code examples
salesforceapex

I can't figure out what is the problem with my apex test


I have this apex class in which I create a pdf file that I send to myself by mail

public with sharing class ApexParser {
    
    @AuraEnabled
    public static String getPdfFileAsBase64String(String className) {
       PageReference pdfPage = Page.envelope;
       pdfPage.getParameters().put('classname', className); 
       Blob pdfBlob = pdfPage.getContent(); 
       String base64Pdf = EncodingUtil.base64Encode(pdfBlob);
       
       return base64Pdf;
    }

    @AuraEnabled
    public static void sendEmailTemplate(String className) {        

        String base64Pdf = getPdfFileAsBase64String(className);
        System.debug('Send mail ');
        System.debug(base64Pdf);
        Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
        attachment.setFileName(className + '.pdf');
        attachment.setBody(EncodingUtil.base64Decode(base64Pdf));

        List<OrgWideEmailAddress> emailAdressess = [
            SELECT Id 
            FROM OrgWideEmailAddress 
            WHERE Address LIKE '[email protected]' 
            LIMIT 1
        ];
        
        Id contactId = '0000000x1';
        Contact cont = [
            SELECT FirstName, LastName, Email, Id
            FROM Contact
            WHERE Id =: contactId
        ];
        List<String> sendTo = new List<String>();
        sendTo.add(cont.Email);

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        mail.setToAddresses(sendTo);
        mail.setSubject('Send mail test');
        mail.setPlainTextBody('000000');
        mail.setOrgWideEmailAddressId(emailAdressess[0].Id);
        mail.setFileAttachments(new Messaging.EmailFileAttachment[]{ attachment });
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
    }
}

And here is my test that produces such an error

@isTest
    public static void testSendEmailTemplate() {
        Test.startTest();
        System.assertEquals(0, Limits.getEmailInvocations());
        try {
            ApexParser.sendEmailTemplate('TestApex');
            System.assertEquals(1, Limits.getEmailInvocations());
        } catch (Exception e) {
            System.assert(false, 'Unexpected error occurred: ' + e.getMessage());
        } 
        Test.stopTest();
    }

System.AssertException: Assertion Failed: Unexpected error occurred: Methods defined as TestMethod do not support getContent call


Solution

  • API Callouts are not allowed in TestMethods unless you specify an HttpCalloutMock method. According to the docs getContent() is treated as an api callout. There are two options for getting around this:

    1. Create an HttpCalloutMock.
     private class Mock implements HttpCalloutMock {
            public HTTPResponse respond(HTTPRequest req) {
                HTTPResponse res = new HTTPResponse();
                res.setBody('Set whatever you want returned here');
                res.setStatusCode(200);
                return res;
            }
        }
    
    @isTest
        public static void testSendEmailTemplate() {
            Test.setMock(HttpCalloutMock.class, new Mock()); 
            Test.startTest();
            System.assertEquals(0, Limits.getEmailInvocations());
            try {
                ApexParser.sendEmailTemplate('TestApex');
                System.assertEquals(1, Limits.getEmailInvocations());
            } catch (Exception e) {
                System.assert(false, 'Unexpected error occurred: ' + e.getMessage());
            } 
            Test.stopTest();
        }
    

    By setting a mock, you return a static response for every callout invoked by the Apex class you are testing. You can see more info about callout mocks here.

    1. Bypassing certain code blocks when running tests (not usually recommended)

    If for some reason you are unable to test certain blocks of code, you can skip those blocks by adding the following if statement to the apex method you are testing:

    if (!Test.isRunningTest()){
        // The logic you would want to skip goes in here.
        // Again, this is not recommended as you will not actually be testing your code, but this is another option.
    }
    

    You can read more about this method here.