I have spent almost 8 hours trying to figure out why my test class isn't working but to no avail. I have simplified and de-bulkfifed the test class to insert only 1 record each for the relevant objects and it still doesn't work. My trigger is the culprit and I can't debug why it isn't allowing my test class to run. The issue occurs when my test class tries to create a case.
I fail to understand that why I can't insert a simple case using my test class. Why is my apex trigger isn't allowing it? Any input would be much appreciated!
Main trigger: It will prevent each user from creating more than certain cases in the current month (Specified by custom setting- MaxCases ). The trigger runs fine and does what it's supposed to do on the UI.
Trigger
trigger LimitCases on Case (before insert) {
//Extract the custom setting value into a variable
Max_Cases__c maxCase = Max_Cases__c.getInstance('maxcasesetting');
Integer maxNoCases = Integer.valueof(maxCase.MaxCases__c);
System.debug('The max no. of cases setting is:' + maxNoCases);
/*1. Create a set of all Owner Id's whose cases are being fed for import
Also, Add all userIds to a map with 0 number of cases as initial values */
if(maxNoCases!=null) {
Map<Id,Integer> ownerCasesMap = new Map<Id,Integer>();
Set<String> ownerIds = new Set<String>();
for(Case newCase: Trigger.new) {
System.debug('Creating a set of Owner Ids');
ownerIds.add(newCase.OwnerId);
ownerCasesMap.put(newCase.OwnerId,0);
}
/*2. Create a user Map just to obtain the Owner Name using their Id
Salesforce doesn't allow doing Owner.name for some incomprehensible reason! */
Map<Id,User> userMap = new Map<Id,User>();
List<User> userM =[SELECT Id, Name FROM User WHERE Id IN: ownerIds];
for(User ownerUser:userM) {
userMap.put(ownerUser.Id, ownerUser);
}
//3. Use AggregateResults to get a count of all Cases pertaining to the above owners
System.debug('Creating a list of grouped results[AggregateResults] now');
List<AggregateResult> groupedResults= [SELECT OwnerId , count(Id) FROM Case
WHERE OwnerId IN:ownerIds
AND CreatedDate= THIS_MONTH
GROUP BY OwnerId];
//4. Use the previously created Map to store Owner Id and the number of Cases from above
for(AggregateResult countCase: groupedResults) {
System.debug('Entered the AggregateResult For loop');
if(countCase!=null) {
System.debug('Owner Id:' + countCase.get('OwnerId'));
System.debug('Count is' + countCase.get('expr0'));
//Map now has key-> Owner Id, value-> Case count
//This will replace the owners previous put in the Map with new values and not put anything for NULL
//This way users who didn't create any cases this month are retained in the previously created map
ownerCasesMap.put((Id)countCase.get('OwnerId'), (Integer)countCase.get('expr0'));
}
}
//Go through every Case being inserted , find the case count from above and compare to maxCases
for(Case newCase: Trigger.new) {
System.debug('Entered the main Case Trigger.new!');
//Get the number of cases associated with the Owner Id of this case
Integer numCases = ownerCasesMap.get(newCase.OwnerId);
System.debug('Number of Cases created so far by this owner:'+ numCases);
//Do not allow the user to create a case if the limit is reached
if(numCases>=maxNoCases) {
System.debug('Entered the if loop in order to show the error since numCases>=maxNoCases' );
newCase.addError('Too many cases created this month for user' + ' ' + userMap.get(newCase.OwnerId).Name + '(' + newCase.OwnerId + '):' + ' ' + maxNoCases);
}
else {
System.debug('Entered the else loop in order to let the user create the case' );
ownerCasesMap.put(newCase.OwnerId, ownerCasesMap.get(newCase.OwnerId) + 1);
System.debug('Number of cases for this owner has been incremented in the map' );
System.debug('Number of cases for this owner: ' + userMap.get(newCase.OwnerId).Name + 'is: ' +ownerCasesMap.get(newCase.OwnerId));
}
}
System.debug('Case has been inserted' );
}
}
**Test class*:*
Error Message System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, LimitCases: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.LimitCases: line 5, column 1: []
Stack Trace Class.TestLimitCases1.testLimitCases1: line 49, column 1
Line 49 is where I do insert newCase;
Line 5, column 1 is Integer maxNoCases = Integer.valueof(maxCase.MaxCases__c);
@isTest
public class TestLimitCases1 {
static testMethod void testLimitCases1() {
//Principle #1: Create records from scratch
//1. Create the custom setting
Max_Cases__c maxcasesetting = new Max_Cases__c();
maxcasesetting.MaxCases__c = 10;
maxcasesetting.Name = 'maxcases';
insert maxcasesetting;
System.debug('Max number of cases:' + maxcasesetting.MaxCases__c);
//2. Insert 1 user
User owner= new User();
owner.FirstName='mayak';
owner.LastName='vasatava';
owner.Alias = 'sriv123';
owner.UserName = 'randomguy@clearstructure.com';
owner.CommunityNickname = 'mangu';
owner.Email ='randomguy@gmail.com';
owner.ProfileId='00e80000000xDnf';
owner.TimeZoneSidKey = 'GMT';
owner.LocaleSidKey = 'en_US';
owner.EmailEncodingKey = 'UTF-8';
owner.LanguageLocaleKey = 'en_US';
insert owner;
System.debug('Inserted users Id is: ' + owner.Id);
//3. Insert Case
System.runas(owner) {
Case newCase = new Case();
newCase.Subject = 'Issue';
newCase.Description = 'Issue Description';
newCase.Status = 'Open';
// try {
insert newCase;
// } catch (Exception e) {
// System.debug('Why is this happening?');
// }
//Principle #2: Test things that should work
Integer newCasesu1Count = [SELECT count() FROM Case];
System.assertEquals(1, newCasesu1Count);
//Principle #3: Test things that shouldn't work
Case newCase1 = new Case();
newCase1.Subject = 'Issue';
newCase1.Description = 'Issue Description';
newCase1.Status = 'Open';
insert newCase1;
Integer newCount = [SELECT count() fROM Case];
System.assertEquals(10, newCount);
}
}
}