1

I'm having issues with getting my 4 Apex triggers, and 1 Apex class deployed to my production environment.

My problem is that when i'm trying to create the @isTest functions to test this trigger, i'm getting a message during validation saying:

Methods defined as TestMethod do not support Web service callouts

Here's my trigger code. It could be a lot neater since I've been making a lot of modifications today in an effort to get it working. I'll tidy up the code later once I've managed to get it working:

trigger IOT_Account_Link on Account (after update, after insert, after undelete, before delete) {
    String action = '';
    if(Trigger.isUpdate) {
        action = 'Update';
    }
    else if(Trigger.isInsert) {
        action = 'New';
    }
    else if(Trigger.isDelete) {
        action = 'Deactivate';
    }
    else if(Trigger.isUnDelete) {
        action = 'Activate';
    }

    if(Trigger.isInsert || Trigger.isUnDelete || Trigger.isUpdate) {
        for(Account a : Trigger.new) {
            JSONGenerator gen = JSON.createGenerator(true);
            gen.writeStartObject();
            gen.writeObjectField('data',a);
            gen.writeObjectField('Action',action);
            gen.writeObjectField('APIKey', IOT_IntegrityAjaxPush.ApiKey);
            gen.writeEndObject();
            String jsonString = gen.getAsString();
            IOT_IntegrityAjaxPush.pushObject(action,'Account',jsonString);
        }
    }

    if(Trigger.isDelete) {
        for(Account a : Trigger.old) {
            JSONGenerator gen = JSON.createGenerator(true);
            gen.writeStartObject();
            gen.writeObjectField('data',a);
            gen.writeObjectField('Action',action);
            gen.writeObjectField('APIKey', IOT_IntegrityAjaxPush.ApiKey);
            gen.writeEndObject();
            String jsonString = gen.getAsString();
            IOT_IntegrityAjaxPush.pushObject(action,'Account',jsonString);
        }
    }
}

As part of the trigger, it makes a call to my Apex class which handles the update back to our bespoke Internal CRM system using a web service callout.

Here's my test function:

@isTest
private class IOT_Apex_Tests {
    @isTest static void test_Trigger_Account() {
        Account a = new Account(Name='Test Account');
        insert a;

        Account b = [SELECT Id,Name FROM Account WHERE Id=:a.Id];
        b.Name = 'New Name';
        update b;

        Account[] c = [SELECT Id,Name FROM Account WHERE Id=:a.Id];
        delete c;

        Account d = [SELECT Id,Name FROM Account WHERE Id=:a.Id ALL ROWS];
        undelete d;
    }
}

My problem is that without doing some form of test script, i'm not going to have enough code coverage, so I need to do something in order to test that the trigger at least makes that call to the Apex class.

Is there a way, from inside the trigger itself, to detect if the trigger is being tested and then omit the executing of that class function ? And if there is, will that then cause issues because i'm then not testing the Apex class at all ?

If anyone can spot where i'm going wrong, or perhaps point me in the right direction. I have to admit i'm fairly new to Apex and Salesforce development, so it's probably me and my 'stuck in my PHP ways' development mentality. :)

For completeness i'll also include a modified copy of the Apex Class that i'm using to push up the change to our bespoke internal system.

public with sharing class IOT_IntegrityAjaxPush {
    public static String ApiURI = '<Not included for security reasons>';
    public static String ApiKey = '<Not included for security reasons>';

    @future (callout=true)
    public static void pushObject(string action, string objectName, string objectdata) {
        HttpRequest req = new HttpRequest();
        req.setEndpoint(ApiURI + '&Action=' + action);
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setBody(objectdata);

        Http http = new Http();
        HTTPResponse res = http.send(req);
    }
}

1 Answer 1

5

The basics are always the same. You need to set a mock in your test.

Typically that would look something like:

@IsTest
class MyTest
{
    class MyMock implements HttpCalloutMock
    {
        public HTTPResponse respond(HTTPRequest request)
        {
            // Create a fake response.
            // Set response values, and 
            // return response.
        }
    }
    @IsTest
    static void myTestMethod()
    {
        Test.setMock(HttpCalloutMock.class, new MyMock());
        // perform operation which invokes callout
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .