+ Start a Discussion
Siddharth LakhotiaSiddharth Lakhotia 

Problem with Test Class?

Apex Trigger : 

trigger preventChangeOfAccountName on Order (before insert) {
    
    Map<String, String> mapSourceOrderIdToAccount = new Map<String, String>();
    
Profile p = [SELECT Id, Name FROM Profile WHERE Name LIKE 'Thailand%' OR Name LIKE 'System Administrator' LIMIT 1];
if(p.Id != UserInfo.getProfileId())
return;
    
for (Order obj : trigger.new){

        mapSourceOrderIdToAccount.put(obj.getCloneSourceId(), null);

    }

    for(Order objOrder : [Select id, AccountId from Order where id in : mapSourceOrderIdToAccount.keySet() Limit 5000]){

        mapSourceOrderIdToAccount.put(objOrder.id, objOrder.AccountId);

    }

     

    for (Order o : trigger.new){

       If  (o.isClone() && mapSourceOrderIdToAccount.get(o.getCloneSourceId()) <> o.AccountId)

       {

           o.addError('Account Name for Cloned records cant be changed');

       }

    }

}


Test Class : 

@isTest
public class preventChangeOfAccountNameTestClass {
    

    static testmethod void profileDetails(){
        
        Profile p = [SELECT Id FROM Profile WHERE Name='Standard User']; 
        
            User u = new User(Alias = 'standt', Email='standarduser@testorg.com', 
            EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
            LocaleSidKey='en_US', ProfileId = p.Id, 
            TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');
        
    }
    
    static testmethod void preventAccNameChange(){  
        
        

Account acc = new Account();
        acc.name='TestAccount1';
        insert acc;
Order ord = new Order();
           ord.AccountId = acc.Id;
           ord.EffectiveDate = System.Today();
          ord.EndDate = System.Today()+5;
        ord.Status = 'NA';
        ord.Offer_Status__c = 'Open';
       insert ord;
      
        try{
            
            Account objNewAc = new Account();
            objNewAc.Name = 'Test account record';
            insert objNewAc;

            Order objNewOrder = ord.clone(false, true);
            objNewOrder.AccountId= objNewAc.Id;
            insert objNewOrder;

        }
        catch(DMLexception e){
           Boolean expectedExceptionThrown =  e.getMessage().contains('Account Name for Cloned records cant be changed') ? true : false;
           System.AssertEquals(expectedExceptionThrown, true);
    }
}
}


However, It covers only 36% code.

 
Jack Yu@TokyoJack Yu@Tokyo
Hi did you got any error message ?(Completed or Failed)
I run your code, completed, and i got 90% code.

User-added image 



User-added image
Siddharth LakhotiaSiddharth Lakhotia
Hi Jack,

I am just getting 36% code coverage.. Can you help me understand why ?User-added image
Jack Yu@TokyoJack Yu@Tokyo
Hi, i guess the problem of your coverage is code below. 
if(p.Id != UserInfo.getProfileId())

because the login user is diffrenct from administrator.
so that , the testclass is stop by return statement.

please make sure user id is same,
i just add three line to your class.
Run again, and look see log output. 



------------------------------------------------------------------------



trigger preventChangeOfAccountName on Order (before insert) {
    
    Map<String, String> mapSourceOrderIdToAccount = new Map<String, String>();
    
Profile p = [SELECT Id, Name FROM Profile WHERE Name LIKE 'Thailand%' OR Name LIKE 'System Administrator' LIMIT 1];

system.debug('p.Id⇒⇒⇒⇒'+p.Id);
system.debug('UserInfo.getProfileId()⇒⇒⇒⇒'+UserInfo.getProfileId());
system.debug('Compare Result is ⇒⇒⇒⇒'+p.Id != UserInfo.getProfileId());


if(p.Id != UserInfo.getProfileId())
return;
    
for (Order obj : trigger.new){

        mapSourceOrderIdToAccount.put(obj.getCloneSourceId(), null);

    }

    for(Order objOrder : [Select id, AccountId from Order where id in : mapSourceOrderIdToAccount.keySet() Limit 5000]){

        mapSourceOrderIdToAccount.put(objOrder.id, objOrder.AccountId);

    }

     

    for (Order o : trigger.new){

       If  (o.isClone() && mapSourceOrderIdToAccount.get(o.getCloneSourceId()) <> o.AccountId)

       {

           o.addError('Account Name for Cloned records cant be changed');

       }

    }

}
Siddharth LakhotiaSiddharth Lakhotia
Yes, the id's for is different. But why is this happening and how can I repair it
Jack Yu@TokyoJack Yu@Tokyo
Just use User of Profile(administrator or Thailand something) to run the testclass you created.
Or just add System.runAs code.

User userItem1 = [Select id,Name From User Where isActive = true AND Profile.Name = 'System Administrator' limit 1];
System.runAs(userItem1) {

}
--------------------------------------------------------------------------------------------------
@isTest
public class preventChangeOfAccountNameTestClass {
    

    static testmethod void profileDetails(){
        
        Profile p = [SELECT Id FROM Profile WHERE Name='Standard User']; 
        
            User u = new User(Alias = 'standt', Email='standarduser@testorg.com', 
            EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
            LocaleSidKey='en_US', ProfileId = p.Id, 
            TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');
        
    }
    
    static testmethod void preventAccNameChange(){  
    
    
    User userItem1 = [Select id,Name From User Where isActive = true AND Profile.Name = 'System Administrator' limit 1];
    System.runAs(userItem1) {


Account acc = new Account();
        acc.name='TestAccount1';
        insert acc;
Order ord = new Order();
           ord.AccountId = acc.Id;
           ord.EffectiveDate = System.Today();
          ord.EndDate = System.Today()+5;
        ord.Status = 'NA';
        ord.Offer_Status__c = 'Open';
       insert ord;
      
        try{
            
            Account objNewAc = new Account();
            objNewAc.Name = 'Test account record';
            insert objNewAc;

            Order objNewOrder = ord.clone(false, true);
            objNewOrder.AccountId= objNewAc.Id;
            insert objNewOrder;

        }
        catch(DMLexception e){
           Boolean expectedExceptionThrown =  e.getMessage().contains('Account Name for Cloned records cant be changed') ? true : false;
           System.AssertEquals(expectedExceptionThrown, true);
    }
    
    }
        
        


}
}
Siddharth LakhotiaSiddharth Lakhotia
Still same code coverage. Any changed in trigger
Jack Yu@TokyoJack Yu@Tokyo
Hi , i guess the code below get user of profile Thailand,but not the administrator

Profile p = [SELECT Id, Name FROM Profile WHERE Name LIKE 'Thailand%' OR Name LIKE 'System Administrator' LIMIT 1];

can you modify it like code below? The problem is 【OR】 of the SOQL statement.

Your Apex Trigger Code:

Profile p = [SELECT Id, Name FROM Profile WHERE Name LIKE 'System Administrator' LIMIT 1];  //I think it will be ok now
Siddharth LakhotiaSiddharth Lakhotia
Hi, 

But I want it to run for Thailand Users l which has 5 profiles... i want it to run for all 5 profiles
Jack Yu@TokyoJack Yu@Tokyo
Hi , you can run your TestClass for 5 times (Thailand Users which has 5 profiles ) 
code as below.  




------------------------------------------------------------------------------------------------------------------------
Apex Trigger : 
------------------------------------------------------------------------------------------------------------------------

trigger preventChangeOfAccountName on Order (before insert) {
    
    Map<String, String> mapSourceOrderIdToAccount = new Map<String, String>();

//i Comment out three lines below.
//Profile p = [SELECT Id, Name FROM Profile WHERE Name LIKE 'Thailand%' OR Name LIKE 'System Administrator' LIMIT 1];
//if(p.Id != UserInfo.getProfileId())
//return;
    
for (Order obj : trigger.new){

        mapSourceOrderIdToAccount.put(obj.getCloneSourceId(), null);

    }

    for(Order objOrder : [Select id, AccountId from Order where id in : mapSourceOrderIdToAccount.keySet() Limit 5000]){

        mapSourceOrderIdToAccount.put(objOrder.id, objOrder.AccountId);

    }

     

    for (Order o : trigger.new){

       If  (o.isClone() && mapSourceOrderIdToAccount.get(o.getCloneSourceId()) <> o.AccountId)

       {

           o.addError('Account Name for Cloned records cant be changed');

       }

    }

}


------------------------------------------------------------------------------------------------------------------------
Test Class : 
------------------------------------------------------------------------------------------------------------------------

@isTest
public class preventChangeOfAccountNameTestClass {
    

    static testmethod void profileDetails(){
        
        Profile p = [SELECT Id FROM Profile WHERE Name='Standard User']; 
        
            User u = new User(Alias = 'standt', Email='standarduser@testorg.com', 
            EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
            LocaleSidKey='en_US', ProfileId = p.Id, 
            TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');
    }
    
    static testMethod void commonTest() {
        Account acc = new Account();
        acc.name='TestAccount1';
        insert acc;
        Order ord = new Order();
        ord.AccountId = acc.Id;
        ord.EffectiveDate = System.Today();
        ord.EndDate = System.Today()+5;
        ord.Status = 'NA';
        ord.Offer_Status__c = 'Open';
        insert ord;
      
        try{
            
            Account objNewAc = new Account();
            objNewAc.Name = 'Test account record';
            insert objNewAc;

            Order objNewOrder = ord.clone(false, true);
            objNewOrder.AccountId= objNewAc.Id;
            insert objNewOrder;

        }
        catch(DMLexception e){
           Boolean expectedExceptionThrown =  e.getMessage().contains('Account Name for Cloned records cant be changed') ? true : false;
           System.AssertEquals(expectedExceptionThrown, true);
    }
    }
    
    //it is for administraotr
    static testmethod void preventAccNameChange_administrator(){  
        User userItem1 = [Select id,Name,Profile.Name From User Where isActive = true AND Profile.Name = 'System Administrator' limit 1];
        system.debug('userItem1 ⇒⇒⇒⇒'+userItem1);
        
        System.runAs(userItem1) {
           commonTest();
        }
    }
    
   //it is for Thailand , just modify the profile name as your real profile name. 
    static testmethod void preventAccNameChange_Thailand1(){  
        User userItem1 = [Select id,Name,Profile.Name From User Where isActive = true AND Profile.Name = 'Thailand1111' limit 1];
        system.debug('userItem1 ⇒⇒⇒⇒'+userItem1);
        
        System.runAs(userItem1) {
           commonTest();
        }
    }
    
   //it is for Thailand , just modify the profile name as your real profile name. 
    static testmethod void preventAccNameChange_Thailand2(){  
        User userItem1 = [Select id,Name,Profile.Name From User Where isActive = true AND Profile.Name = 'Thailan2222' limit 1];
        system.debug('userItem1 ⇒⇒⇒⇒'+userItem1);
        
        System.runAs(userItem1) {
           commonTest();
        }
    }
    
   //it is for Thailand , just modify the profile name as your real profile name. 
    static testmethod void preventAccNameChange_Thailand3(){  
        User userItem1 = [Select id,Name,Profile.Name From User Where isActive = true AND Profile.Name = 'Thailan3333' limit 1];
        system.debug('userItem1 ⇒⇒⇒⇒'+userItem1);
        
        System.runAs(userItem1) {
           commonTest();
        }
    }
    
   //it is for Thailand , just modify the profile name as your real profile name. 
    static testmethod void preventAccNameChange_Thailand4(){  
        User userItem1 = [Select id,Name,Profile.Name From User Where isActive = true AND Profile.Name = 'Thailan4444' limit 1];
        system.debug('userItem1 ⇒⇒⇒⇒'+userItem1);
        
        System.runAs(userItem1) {
           commonTest();
        }
    }
    
   //it is for Thailand , just modify the profile name as your real profile name. 
    static testmethod void preventAccNameChange_Thailand5(){  
        User userItem1 = [Select id,Name,Profile.Name From User Where isActive = true AND Profile.Name = 'Thailan5555' limit 1];
        system.debug('userItem1 ⇒⇒⇒⇒'+userItem1);
        
        System.runAs(userItem1) {
           commonTest();
        }
    }
    
}
Siddharth LakhotiaSiddharth Lakhotia

There are 30 profies in the system, I want the trigger for oly 5 profiles.. Does this code ensure, that code will be running only for Thailand Users and not for any other profile

If yes, Can you please explain how ?

Jack Yu@TokyoJack Yu@Tokyo
1. yes, this code will ensure only 5 profiles will be run.
just replace your profile to Thailand1111, Thailand2222,Thailand3333,Thailand4444,Thailand5555

2. you need to know something about System.runAs

you can read the url below about System.rusAs,
【Using the runAs Method】
https://developer.salesforce.com/docs/atlas.en-us.212.0.apexcode.meta/apexcode/apex_testing_tools_runas.htm
【what is system.runas() can any one explain how can we use it?】
https://developer.salesforce.com/forums/?id=906F0000000kFFIIA2