[SalesForce] How to create the case with an attachment and topics using Test class

I want to create a case which has an attachment, Billing Account, and topics. Given below is the code from my Test Class:

Scenario: Once user submit the case request and ask for approval. The request goes to the Manager for approval, once the request approves, an email goes to Legal team with an Case attachments in an email.

Topic__c tc = new Topic__c(Name ='My New topic');
Attachment att = new Attachment(Name = 'sample.pdf');

Case c = new Case(Origin = 'Phone',
                          Subject = 'New Testing',
                          Department__c = 'XXXXXXX', Priority = 'Normal',
                          Topic__c = tc.Id,
                          Risk_Approval__c = true);
insert c;

I am getting the below error:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CaseTrigger: execution of BeforeInsert

My Trigger class:

trigger sendEAttachmentsInMail on Case (before insert, before update){

for(Case casevar : Trigger.new){

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        mail.setBccSender(false);
        mail.setUseSignature(false);
        mail.setTargetObjectId(casevar.Id);
        mail.setTemplateId('XXXXXXXXX');
        mail.saveAsActivity = false;

      //Set email file attachments
        List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>();
        for (Attachment a : [select Name, Body, BodyLength from Attachment where ParentId = :casevar.Id])
        {
        // Add to attachment file list
        Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
        efa.setFileName(a.Name);
        efa.setBody(a.Body);
        fileAttachments.add(efa);
        }
        mail.setFileAttachments(fileAttachments);
      //Send email
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });     
    }
}

Best Answer

One thing you should fix is to bulkify your sendEmail call. You only get 10 invocations per transaction, so even inserting 11 Case records will hit a LimitException. You also have a query you need to bulkify (on Attachment).

Email Bulkification

List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
for (Case record : trigger.new)
{
    Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
    // set attributes
    emails.add(email);
}
Messaging.sendEmail(emails);

Query Bulkification

Map<Id, List<Attachment>> attachments = new Map<Id, List<Attachment>>();
for (Attachment record : [
    SELECT Name, Body FROM Attachment
    WHERE ParentId IN :trigger.newMap.keySet()
]){
    if (!attachments.containsKey(record.ParentId))
        attachments.put(record.ParentId, new List<Attachment>());
    attachments.get(record.ParentId).add(record);
}

for (Case record : trigger.new)
{
    List<Attachment> relatedAttachments = attachments.get(record.Id);
    if (relatedAttachments != null)
    {
        // add attachments an email
    }
    // add email to collection
}
// send emails
Related Topic