2

I have been googling around and found several blogs for Apex REST unit testing both pre and post v24, but I am hitting a dead end writing out a unit test for an Apex REST service that merges two contact records:

@RestResource(urlMapping='/ContactMerge/*')
global with sharing class contactMerge {

    @HttpPost
    global static String doPost(String cid1, String cid2) {
        //List<Contact> cls = new List<Contact>{new Contact(id=cid1),new Contact(id=cid2)}

        Contact maCntct = [SELECT Id FROM Contact WHERE Id = :cid1];
        Contact meCntct = [SELECT Id FROM Contact WHERE Id = :cid2];
        try{
            merge maCntct meCntct;        
            return maCntct.Id;
        } catch (DmlException e) {
            return 'failed';
        }
    }
}

And here's the Unit Test class I have so far:

@isTest 
private class mergeRecordsTest {

    private static testMethod void contactMergeTest() {

        Account acc1 = new                         
            Account(name='McRestieTest',Account_Region__c='NAM',Account_Sub_Region__c='West');

        try {
            insert acc1;
            //return acc1.Id;
        }
        catch (DmlException e) {
            //return 'failed';
        }

        Contact c1 = new Contact(FirstName='Tryler',LastName='McTrevz',AccountId=acc1.Id,Contact_Region__c='NAM',
                                 Contact_Sub_Region__c='West',ContactVertical__c='Media & Entertainment',Contact_Sub_Vertical__c='Radio',
                                 Email='tmcshev@tryler.com');

        Contact c2 = new Contact(FirstName='Tryler',LastName='McTrevorz',AccountId=acc1.Id,Contact_Region__c='NAM',
                                 Contact_Sub_Region__c='West',ContactVertical__c='Media & 
                                 Entertainment',Contact_Sub_Vertical__c='Radio',
                                 Email='tmcshev@tryler.com');

        List<Contact> clist = new List<Contact>();
        clist.add(c1);
        clist.add(c2);

        insert clist;

        string requestPayload = '{"cid1":c1.Id,"cid2":c2.Id}';

        RestRequest req = new RestRequest();
        RestResponse res = new RestResponse();

        req.requestURI = 
            'https://XXXX.salesforce.com/services/apexrest/ContactMerge';
        req.httpMethod = 'POST';

        RestContext.request = req;
        RestContext.response = res;


        Test.startTest();

        /*This line errors out and does not compile:
        Method does not exist or incorrect signature: void doPost(String) */
        contactMerge.doPost(requestPayload);
        Test.stopTest();

        String testBlob = res.responseBody.toString();`

I think all I need to do next is:

  1. Figure out why the line contactMerge.doPost(requestPayload); is erroring out and not recognizing the Class's signature
  2. systemAssert that the responseBody contains the cid1 Id value
  3. Also, how can I dynamically pass in the salesforce domain? My sandbox domain is different than my Production org or does that not matter?

Am I on the right track?

3

Figure out why the line contactMerge.doPost(requestPayload); is erroring out and not recognizing the Class's signature

Your method accepts two parameters. The automatic JSON parsing isn't something you test in your unit test. Instead, just pass the parameters directly:

contactMerge.doPost(c1.Id, c2.Id);

systemAssert that the responseBody contains the cid1 Id value

You're not using responseBody directly; you're returning a String value. So you just do this:

String result = contactMerge.doPost(c1.Id, c2.Id);
System.assertEquals(result, c1.Id);

Also, how can I dynamically pass in the salesforce domain? My sandbox domain is different than my Production org or does that not matter?

Doesn't matter. The only way you'd care is if you were putting values in to your URL, which you're not, and even then, you'd only care about parsing out an Id or something.

However, for future reference, if you need the Salesforce URL for an org:

String baseUrl = Url.getSalesforceBaseUrl().toExternalForm();

To complete your coverage, you might try passing in a null value so you can cover the try-catch block as well:

String result = contactMerge.doPost(c1.Id, null);
System.assertEquals(result, 'failed');
  • This is epic, thanks @sfdcfox! Oddly I kept getting 'List has no rows for assignment to SObject' errors with the 'String result = contactMerge.doPost(c1.Id, null); System.assertEquals(result, 'failed');' test. I System.Debug()'d to see if the c1.Id was getting dropped but that value is still returned. Any idea why the second System.assertEquals() is failing? – GPP Mar 26 '18 at 17:29
  • 1
    @GPP Oh, I just realized you're querying both. Maybe you should put the queries inside the try-catch block, then, otherwise you might not have a way to test merge failures or get 100% coverage. – sfdcfox Mar 26 '18 at 17:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.