1

I have created three fields on Account to store information on the duplicates in the system. Standard duplicate rules apply. The fields are:

  • Duplikat__c: a checkbox
  • ID_Doppelte_Datensaetze__c: Id from the table DuplicateRecordSet
  • Duplikat_Notiz__c: stores information on duplicates

The class to populate the three fields works fine and is as follows:

public class UpdateDuplicateAccounts {

public UpdateDuplicateAccounts(){
    detectAndUpdateDuplicates();    
}

public static void detectAndUpdateDuplicates(){

    //Select all duplicates in the system
    list <DuplicateRecordItem> listDupRecItem = [SELECT DuplicateRecordSetId, Id, IsDeleted, Name, RecordId, DuplicateRecordSet.RecordCount FROM DuplicateRecordItem WHERE IsDeleted = false AND DuplicateRecordSet.RecordCount > 1];
    System.debug(logginglevel.debug, 'Alle Duplikate in der Org: '+listDupRecItem);

    if(listDupRecItem.size() > 0 && listDupRecItem <> null){           

        //get Ids from the corresponding duplicate Accounts
        list <Id> listAccountIds = new list <Id>();
        for (DuplicateRecordItem dupRI: listDupRecItem){
            listAccountIds.add(dupRI.RecordId); 
        }
        System.debug(logginglevel.debug, 'Alle Accounts zu den DuplicateRecordSetIds: '+listAccountIds);

        //Select all newly added duplicate Account records which have not yet been auto-populated
        list <Account> listDuplicateAccounts = [SELECT Id, Duplikat_Notiz__c FROM Account WHERE Id =:listAccountIds AND Duplikat_Notiz__c = ''];
        System.debug(logginglevel.debug, 'Alle Ids von den Account-Duplikaten: '+listDuplicateAccounts);

        //Create new Account list to update records
        list <Account> listAccountsToUpdate = new list <Account>();

        //Check duplicate checkbox and assign Duplicate Id to each Account
        for (DuplicateRecordItem dRI: listDupRecItem) {
            for (Account acct : listDuplicateAccounts){
                if(acct.Id == dRI.RecordId){
                    acct.Duplikat__c = true;
                    acct.ID_Doppelte_Datensaetze__c = dRI.DuplicateRecordSetId;
                    acct.Duplikat_Notiz__c = 'Systemgeneriert';
                    System.debug(logginglevel.debug, 'Account-Update: '+acct);
                    listAccountsToUpdate.add(acct);
                }               
            }
        }

        //update Accounts with information on duplicates
        update listAccountsToUpdate;
    }
}   

}

However, I have problems writing the test class as it seems there is an issue with the order of saving and generating duplicates in the system:

@isTest
  public class UpdateDuplicateAccountsTest {

@isTest
static void clearMessagesTest() {

    //Insert Account
    Account acct = new Account();
    acct.Name = 'Test Account';
    acct.BillingStreet = 'TestStrasse 1';
    acct.BillingCity = 'Test City';
    acct.Phone = '123456789';

    insert acct;

    //Insert duplicate Account
    Database.DMLOptions dml = new Database.DMLOptions(); 
    dml.DuplicateRuleHeader.allowSave = true;
    //dml.DuplicateRuleHeader.runAsCurrentUser = true;
    Account accnt = new Account();
    accnt.Name = 'Test Account';
    accnt.BillingStreet = 'TestStrasse 1';
    accnt.BillingCity = 'Test City';
    accnt.Phone = '123456789';

    Database.SaveResult sr = Database.insert(accnt, dml);
    if (sr.isSuccess()) {
        System.debug('Duplicate account has been inserted in Salesforce!');
    }

    //Run Class to test
    Test.startTest();
        UpdateDuplicateAccounts.detectAndUpdateDuplicates();
    Test.stopTest();

    //Re-Select Duplicate Accounts
    list <Account> listAccount = [SELECT Id, Duplikat__c, ID_Doppelte_Datensaetze__c, Duplikat_Notiz__c FROM Account];
    System.debug(logginglevel.debug, 'Test eingefuegte Accounts'+listAccount);
    list <DuplicateRecordItem> listDupRecItem = [SELECT DuplicateRecordSetId, DuplicateRecordSet.RecordCount FROM DuplicateRecordItem];
    System.debug(logginglevel.debug, 'Test Records in DuplicateRecordItem'+listDupRecItem);

    //Check Checkbox, Id, Note
    //System.assertEquals(true, listAccount[0].Duplikat__c, 'Duplikat nicht angekreuzt');
    //System.assertEquals(listDupRecItem.DuplicateRecordSetId, accnt.ID_Doppelte_Datensaetze__c, 'ID_Doppelte_Datensaetze__c nicht befüllt');
    //System.assertEquals('Systemgeneriert', accnt.Duplikat_Notiz__c, 'Notiz befüllt mit Systemgeneriert');
    //System.assertEquals(200, listDupRecItem.DuplicateRecordSet.RecordCount, 'Notiz befüllt mit Systemgeneriert');
}

}

When I re-select the Accounts in the test class after the test is run on the duplicate Accounts, Duplikat__c is false, both ID_Doppelte_Datensaetze__c and Duplikat_Notiz__c are empty, and there is no entry in the table DuplicateRecordItem.

Is it possible to properly write the test class and make it work? Meaning that the Accounts are really stored as duplicates and identified by the system as such?

1

I will answer the question myself. I had to do a manual insert of DuplicateRecordSet and DuplicateRecordItem(s). So the Test Class looks like that:

@isTest

public class Test_DuplicateAccountUpdate {

@testSetup static void testSetupMethod() {
    //Insert Account
    Account acct = new Account();
    acct.Name = 'Test Account';
    acct.BillingStreet = 'TestStrasse 1';
    acct.BillingCity = 'Test City';
    acct.Phone = '123456789';

    insert acct;
    System.debug(logginglevel.debug, 'acct'+acct);

    //Insert duplicate Account
    Database.DMLOptions dml = new Database.DMLOptions(); 
    dml.DuplicateRuleHeader.allowSave = true;
    Account accnt = new Account();
    accnt.Name = 'Test Account';
    accnt.BillingStreet = 'TestStrasse 1';
    accnt.BillingCity = 'Test City';
    accnt.Phone = '123456789';

    Database.SaveResult sr = Database.insert(accnt, dml);
    if (sr.isSuccess()) {
        System.debug(logginglevel.debug, 'accnt'+accnt);
    }


    DuplicateRecordSet dupRS = new DuplicateRecordSet();
    dupRS.DuplicateRuleId = '0Bm0Y0000051YxtSAE';

    insert dupRS;
    System.debug(logginglevel.debug, 'dupRS'+dupRS);

    DuplicateRecordItem dupRIacct = new DuplicateRecordItem();
    dupRIacct.DuplicateRecordSetId = dupRS.Id;
    dupRIacct.RecordId = acct.Id;    

    insert dupRIacct;
    System.debug(logginglevel.debug, 'dupRIacct'+dupRIacct);

    Database.DMLOptions dmlaccnt = new Database.DMLOptions(); 
    dmlaccnt.DuplicateRuleHeader.allowSave = true;

    DuplicateRecordItem dupRIaccnt = new DuplicateRecordItem();
    dupRIaccnt.DuplicateRecordSetId = dupRS.Id;
    dupRIaccnt.RecordId = accnt.Id;    

    Database.SaveResult sraccnt = Database.insert(dupRIaccnt, dmlaccnt);
    if (sraccnt.isSuccess()) {
        System.debug(logginglevel.debug, 'dupRIaccnt'+dupRIaccnt);
    }
}

@isTest static void clearMessagesTest() {
    //Run Class to test
    Test.startTest();
        DuplicateAccountUpdate.detectAndUpdateDuplicates();
    Test.stopTest();

    //Re-Select Duplicate Accounts
    list <Account> listAccount = [SELECT Id, Duplikat__c, ID_Gruppe_doppelter_Datensatz__c, Info_Duplikat__c FROM Account];
    System.debug(logginglevel.debug, 'Test eingefuegte Accounts'+listAccount);
    list <DuplicateRecordItem> listDupRecItem = [SELECT DuplicateRecordSetId FROM DuplicateRecordItem];
    System.debug(logginglevel.debug, 'Test Records in DuplicateRecordItem'+listDupRecItem);
    list <DuplicateRecordSet> listDupRecSet = [SELECT Id, RecordCount FROM DuplicateRecordSet];

    //Check Checkbox, Id, Note
    System.assertEquals(true, listAccount[0].Duplikat__c, 'Duplikat nicht angekreuzt');
    System.assertEquals('Systemgeneriert', listAccount[0].Info_Duplikat__c, 'Notiz befüllt mit Systemgeneriert');
    System.assertEquals(2, listDupRecSet[0].RecordCount, 'Anzahl Records unterschiedlich');
    System.assertEquals(listDupRecItem[0].DuplicateRecordSetId, listDupRecSet[0].Id, 'Ids des Duplicate Record Sets unterschiedlich');
}

}

Furthermore, on the class to be tested I had to change the update into a database.update with DML options as carried out twice in the test class.

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.