1

Is it possible to programmatically inactive a Record Type?

I'm attempting to write a unit test where I insert a testCase but then need to inactive the Record Type for that testCase somehow. The reason for this is that if a user tries to clone a Case with an inactive Record Type they will get a warning saying that's not allowed. We have a custom clone button and a clone() method that checks whether a Case that is being cloned has an active Record Type. So far, I've been unable to write a unit test for this. Any feedback would be greatly appreciated.

@isTest(SeeAllData=true)
private class CaseCloneControllerTest {

    @isTest
    public static void testCloneCaseInactiveRT(){
        Test.startTest();
        Case testCase = (Case)SmartFactory.createsObject('Case');
        String strRecordTypeId = [SELECT Id FROM RecordType WHERE SObjectType = 'Case' AND IsActive = true LIMIT 1].Id;
        testCase.RecordTypeId = strRecordTypeId;
        insert testCase;

        System.runAs(TestUserFactory.getWwtIntegrationUser()) {
            RecordType rt = [SELECT Id FROM RecordType WHERE Id = :testCase.RecordTypeId];
            rt.isActive = false;
        }

        ApexPages.StandardController sc = new ApexPages.StandardController(testCase);
        CaseCloneController controller = new CaseCloneController(sc);
        PageReference pr = controller.cloneCase();
        //System.assertEquals(null, controller.clonedCase.Id);
        Test.stopTest();
    }
}
6
  • have you tried in your test class to use seeAllData=true ?
    – ihssan
    Jan 25, 2017 at 15:19
  • it's better if you share you code or to tell what error are you getting
    – ihssan
    Jan 25, 2017 at 15:20
  • Thanks for replying. I am currently using seeAllData=true. I'm not getting any errors at the moment but I have not been able to figure out how to inactivate the Record Type for testCase after testCase has been inserted. I'm a beginner so there may be something simple that I'm missing on how to accomplish that or maybe it's not possible but I don't have any other ideas at the moment.
    – Adnan
    Jan 25, 2017 at 15:24
  • as @Santanu Boral mentioned, you cannot perform DML operations in RecordType
    – ihssan
    Jan 25, 2017 at 15:26
  • @ihssan using seeAllData=true is almost always a bad idea, and should hardly ever be suggested.
    – Derek F
    Jan 25, 2017 at 15:27

2 Answers 2

4

Recordtype object doesn't support DML operation, so you cannot create a RecordType from Apex. See sObjects That Don’t Support DML Operations

There are 2 ways you can do testing.

Approach 1

Create a recordtype at your org and make it inactive and try to use the recordtype in your test class.

System.runAs(TestUserFactory.getWwtIntegrationUser()) {
         RecordType rt = [SELECT Id FROM RecordType WHERE Name = :recordTypeName 
                         AND SObjectType = 'Case' 
                         AND isActive=false];           
    }

Approach 2

You can create a mock in cloneCase() method of your Controller and do testing with Test.isRunningTest() and show the error message.

1
  • approach 1 is fragile as some sysad in the future could easily delete the recordtype for wondering why it is there
    – cropredy
    Jan 25, 2017 at 17:53
1

This is where the Separation of Concerns Selector pattern comes in handy - I personally prefer the implementation used in Force.com Enterprise Architecture and now on Trailhead. You create a class RecordTypesSelector that extends fflib_SObjectSelector and you add various methods like getRecordTypesByDeveloperName(String[] listOfDevNames)

The methods in the selector layer are easily mocked ; see AndyInTheCloud blog post for the technique.

For a given unit test, you provide a mock implementation of getRecordTypesByDeveloperName(String[] listOfDevNames) that can return a RecordType sobject that is inactive while for Production code, the actual selector layer query executes and real database sobjects are returned.

You must log in to answer this question.

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