Salesforce Trigger – “DML not allowed on RecordType”

I have created a trigger which is dependant on a custom record type existing. In my test for the trigger, I want to ensure that when this record type doesn’t exist the trigger throws the appropriate exception. Unfortunately I can’t see how I can do this, as DML statements can’t be performed on Record Types. The error message I am getting is: “DML not allowed on RecordType” see the trigger code below:

trigger SetMostRecent on Opportunity (before insert) {

        List<RecordType> recordType = [SELECT id FROM RecordType WHERE Name = 'foo' AND SobjectType = 'Opportunity' limit 1];

        Id recordTypeId; 
        if (recordType.size() > 0) { 

            recordTypeId = recordType[0].Id; 
        }
        else {
            throw new MembershipTypeNotFoundException('blahblah'); 
        }

My test class is as follows:

 static testMethod void myTest() {
    //Creates a valid opportunity. 
    Opportunity opp = Data.ValidOpp(); 
    RecordType type = [SELECT id, Name FROM RecordType WHERE Name = 'foo' AND SobjectType = 'Opportunity'];
    //Line which throws DML not allowed on RecordType
    delete type;
    //should now throw custom exception..
    insert opp; 

 }

Does anyone know a way how I could get around this?

Cheers

Answer

How about some indirection by setting the record type ID on a class that handles the insert. Then in the test class you just set it to null to simulate the record type id not being present. The key would be to only allow it to be set once.

I didn’t actually test any of the code below, but it illustrates my point.

The handler class.

public class SetMostRecentHanlder {

    private static Id recTypeId;
    private static Boolean recTypeSet = false;

    /*
     * Sets the record type id if it hasn't been set during
     * the current transaction already.
     */
    public static void setRecTypeId(Id rId) {
        if (!recTypeSet) {
            recTypeId = rId;
            recTypeSet = true;
        }
    }

    /*
     * Handles the before insert for opportunities.
     * If the recTypeId is not set then a MembershipTypeNotFoundException is thrown
     */
    public static void handleBeforeInsert(List<Opportunity> newList) {
        if (recTypeId == null) {
            throw new MembershipTypeNotFoundException('blah blah blah');
        }
        // Handle processing the newList some how...
    }
}

The trigger:

trigger SetMostRecent on Opportunity (before insert) {
    List<RecordType> recordTypes = [
        SELECT id FROM RecordType 
        WHERE Name = 'foo' AND SobjectType = 'Opportunity' limit 1
    ];
    if (!recordTypes.isEmpty()) {
       // Remember, the recType will only get set if setter not called before.
       SetMostRecentHanlder.setRecTypeId(recordTypes.get(0).Id);
    }
    // could pass Trigger.newMap if need map instead
    SetMostRecentHanlder.handleBeforeInsert(Trigger.new);
}

The test methods

static testMethod void testInsertWhenNoRecType() {
    SetMostRecentHanlder.setRecTypeId(null);
    Opportunity opp = Data.ValidOpp(); 
    try {
        insert opp;
    } catch (MembershipTypeNotFoundException expected) {
        System.assert(true, 'Expected to catch exception ' + expected);
    }
}
static testMethod void testInsertWhenRecTypePresent() {
    // Don't set rec type, so that trigger will
    // set it to the value in the DB.
    Opportunity opp = Data.ValidOpp(); 
    insert opp;

    // Assert something here.
}

Attribution
Source : Link , Question Author : Jim , Answer Author : Peter Knolle

Leave a Comment