function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Brian Cherry FWIBrian Cherry FWI 

Test Class Attachment issue

I'm writing a test class for my controller but I'm having issues with the attachment portion. Here is the error:

System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Name, Body]: [Name, Body]
Stack Trace: Class.expenseController.upload: line 82, column 1 Class.TestExpenseController.testAddAttachmentToObject: line 38, column 1

Here is the Test Class:
@istest
public class TestExpenseController{

    static Expense_Line_Items__c setupServiceLineItem(final Expense_Report__c partner) {
        Expense_Line_Items__c lineItem = new Expense_Line_Items__c();
        lineItem.Expense_Report__c = partner.Id;
        insert lineItem;
        return lineItem;
    }

    static Expense_Report__c setupServicePartner() {
        Purchase_Request__c project = (Purchase_Request__c)new SObjectBuilder(Purchase_Request__c.SObjectType).buildAndInsert()[0];
        Expense_Report__c partner = new Expense_Report__c();
        partner.Purchase_Request__c = project.Id;
        insert partner;
        return partner;
    }

    static Attachment setupAttachment(final Expense_Report__c partner) {
        Purchase_Request__c project = (Purchase_Request__c)new SObjectBuilder(Purchase_Request__c.SObjectType).buildAndInsert()[0];
     Blob b = Blob.valueOf('Test Data');
     Attachment attachment = new Attachment();
     attachment.ParentId = partner.Id;
     attachment.Name = 'Test Attachment for Parent';
     attachment.Body = b;
     insert attachment;
     return attachment;

    }

static testmethod void testAddAttachmentToObject() {

Expense_Report__c aBasicPartner = setupServicePartner();
Attachment associatedAttachment  = setupAttachment(aBasicPartner); 
Test.startTest();
Test.setCurrentPage(Page.PSview);
 ExpenseController deliverablesCnt = new ExpenseController(new ApexPages.StandardController(aBasicPartner));
  deliverablesCnt.upload();
    Test.stopTest(); 
     List<Attachment> attachments=[select id, name from Attachment where parent.id=: aBasicpartner.Id];
     System.assertEquals(1, attachments.size());

    }


    static testmethod void deliverablesCnt_Should_QueryPartnerLineItemsOnCreate(){
        //Given
        Expense_Report__c aBasicPartner = setupServicePartner();
        Expense_Line_Items__c associatedPartnerLineItem  = setupServiceLineItem(aBasicPartner);
        //when
        Test.startTest();
            Test.setCurrentPage(Page.PSview);
            expenseController deliverablesCnt = new expenseController(new ApexPages.StandardController(aBasicPartner));
        Test.stopTest();
        //then
        System.assertEquals(1, deliverablesCnt.getDeliverables().size(), 'Should have one line item in delivers');
     
    }

    static testmethod void deliverablesCnt_Should_InsertNewLineItem(){
        //Given
        Expense_Report__c aBasicPartner = setupServicePartner();
        Expense_Line_Items__c associatedPartnerLineItem  = setupServiceLineItem(aBasicPartner);
        //when
        Test.startTest();
            Test.setCurrentPage(Page.PSview);
            ExpenseController deliverablesCnt = new ExpenseController(new ApexPages.StandardController(aBasicPartner));
            deliverablesCnt.insertmethod();
        Test.stopTest();
        //then
        List<Expense_Line_Items__c> associatedLineItems = [
            SELECT Expense_Report__c
            FROM Expense_Line_Items__c
            WHERE Expense_Report__c = :aBasicPartner.Id
        ];
        System.assertEquals(2, associatedLineItems.size(), 'A new service partner line item should have been created and associated');
    }

    static testmethod void deliverablesCnt_Should_SaveLineItemChanges() {
        //Given
        Expense_Report__c aBasicPartner = setupServicePartner();
        Expense_Line_Items__c unsavedLineItem = new Expense_Line_Items__c();
        unsavedLineItem.Expense_Report__c = aBasicPartner.Id;
        //when
        Test.startTest();
            Test.setCurrentPage(Page.PSview);
            ExpenseController deliverablesCnt = new ExpenseController(new ApexPages.StandardController(aBasicPartner));
            deliverablesCnt.getDeliverables().add(unsavedLineItem);
            PageReference pageRef = deliverablesCnt.saveChanges();
        Test.stopTest();
        //then
        List<Expense_Line_Items__c> associatedLineItems = [
            SELECT Expense_Report__c
            FROM Expense_Line_Items__c
            WHERE Expense_Report__c = :aBasicPartner.Id
        ];
        System.assertEquals(1, associatedLineItems.size(), 'The unsaved service partner line item should have been saved');
        System.assertEquals(true, pageRef.getRedirect(), 'Page should redirect');
    }

    static testmethod void deliverablesCnt_Should_DeleteSelectedServiceLineItem() {
        //Given
        final Expense_Report__c aBasicPartner = setupServicePartner();
        final Expense_Line_Items__c associatedPartnerLineItem  = setupServiceLineItem(aBasicPartner);
        final String nonExistingLineItemId = aBasicPartner.Id;

        Test.setCurrentPage(Page.PSview);
        ExpenseController deliverablesCntSelectedLineItem = new ExpenseController(new ApexPages.StandardController(aBasicPartner));
        ExpenseController deliverablesCntNoSelectedLineItem = new ExpenseController(new ApexPages.StandardController(aBasicPartner));
        ExpenseController deliverablesCntNotFoundSelectedLineItem = new ExpenseController(new ApexPages.StandardController(aBasicPartner));

        //when
        Test.startTest();
            PageReference noSelectedLineItemPageRef = deliverablesCntNoSelectedLineItem.DeleteAccount();
            deliverablesCntNotFoundSelectedLineItem.SelectedAccountId = nonExistingLineItemId;
            PageReference notFoundLineItemPageRef = deliverablesCntNotFoundSelectedLineItem.DeleteAccount();
            deliverablesCntSelectedLineItem.SelectedAccountId = associatedPartnerLineItem.Id;
            PageReference selectedLineItemPageRef = deliverablesCntSelectedLineItem.DeleteAccount();
        Test.stopTest();

        //then
        System.assertEquals(true, selectedLineItemPageRef.getRedirect(), 'Page should redirect when selected it is found');
        System.assertEquals(true, notFoundLineItemPageRef.getRedirect(), 'Page should still redirect if selected id was not found');
        System.assertEquals(null, noSelectedLineItemPageRef, 'Page should be null');

        List<Expense_Line_Items__c> associatedLineItems = [
            SELECT Expense_Report__c
            FROM Expense_Line_Items__c
            WHERE Expense_Report__c = :aBasicPartner.Id
        ];
        System.assertEquals(0, associatedLineItems.size(), 'The service partner line item should have been deleted');
    }

    static testmethod void deliverablesCnt_Should_CreateNewLineItem(){
        //Given
        Expense_Report__c aBasicPartner = setupServicePartner();
        Expense_Line_Items__c associatedPartnerLineItem  = setupServiceLineItem(aBasicPartner);
        //when
        Test.startTest();
            Test.setCurrentPage(Page.PSview);
            ExpenseController deliverablesCnt = new ExpenseController(new ApexPages.StandardController(aBasicPartner));
            deliverablesCnt.newDeliverable();
        Test.stopTest();
        //then
        System.assertEquals(2, deliverablesCnt.getDeliverables().size(), 'Should have two line items in delivers as a new one should have been appended');
        System.assertEquals(aBasicPartner.Id, deliverablesCnt.getDeliverables().get(1).Expense_Report__c, 'Id should have been set');
    }


}

Here is the class:
ublic class expenseController {
    // class variables
    PageReference pageRef = new PageReference(ApexPages.currentPage().getUrl());
    Expense_Report__c proj;
    Expense_Line_Items__c[] delivers;
    public string SelectedAccountId {get;set;}

    // Constructor
    public expenseController(ApexPages.StandardController controller) {
        this.proj = (Expense_Report__c) controller.getSubject();
        this.delivers = [SELECT
            d.Name, d.Billable__c, d.Comments__c, d.Travel_type__c, d.Purchase_type__c,
            d.Expense_Report__c, d.Id, d.Purchase_Date__c, 
            d.Quantity__c, d.Sales_Tax__c, d.Shipping__c, 
            d.total__c, d.type__c, d.unit_price__c, d.Description__c,d.Price_Override__c,d.Override_Price__c
            FROM Expense_Line_Items__c d
            WHERE d.Expense_Report__c = : proj.id
        ];
    }

    public pagereference insertmethod() {
        Expense_Line_Items__c cc = new Expense_Line_Items__c();
        cc.Expense_Report__c = proj.id;
        insert cc;
        return null;
    }

    public Expense_Line_Items__c[] getDeliverables() {
        return this.delivers;
    }

    // Action Method called from page button
    public pagereference saveChanges() {
        upsert this.delivers;
        pageRef.setRedirect(true);
        return pageRef;
    }

    // Action Method called from page link
    public pagereference newDeliverable() {
       Expense_Line_Items__c d = new Expense_Line_Items__c();
        d.Expense_Report__c = this.proj.id;
        delivers.add(d);
        getDeliverables();
        return null;
    }

    public pagereference DeleteAccount() {
        // if for any reason we are missing the reference
        if (SelectedAccountId == null) {
            return null;
        }
        // find the account record within the collection
        Expense_Line_Items__c tobeDeleted = null;
        for (Expense_Line_Items__c a: this.delivers)
            if (a.Id == SelectedAccountId) {
                tobeDeleted = a;
                break;
            }
            //if account record found delete it
        if (tobeDeleted != null) {
            Delete tobeDeleted;
        }
        pageRef.setRedirect(true);
        return pageRef;
    }
 //Attachments
   public Attachment attachment {
  get {
      if (attachment == null)
        attachment = new Attachment();
      return attachment;
    }
  set;
  }

  public PageReference upload() {

    attachment.OwnerId = UserInfo.getUserId();
    attachment.ParentId =  proj.id;
    attachment.IsPrivate = false;
      insert attachment;
      pageRef.setRedirect(true);
      return pageRef;
    }


  }

Any help would be greatly appreciated!
 
Best Answer chosen by Brian Cherry FWI
@Karanraj@Karanraj
In the main class, you are not setting any value for Name and body field of the attachment object [which is required field for attachment]
Set the value for name and body field in the upload method
public PageReference upload() {

    attachment.Name = 'Name of the attachment';
    attachment.body = 'Blob content';
    attachment.OwnerId = UserInfo.getUserId();
    attachment.ParentId =  proj.id;
    attachment.IsPrivate = false;
    insert attachment;
    pageRef.setRedirect(true);
    return pageRef;

 }

 

All Answers

@Karanraj@Karanraj
In the main class, you are not setting any value for Name and body field of the attachment object [which is required field for attachment]
Set the value for name and body field in the upload method
public PageReference upload() {

    attachment.Name = 'Name of the attachment';
    attachment.body = 'Blob content';
    attachment.OwnerId = UserInfo.getUserId();
    attachment.ParentId =  proj.id;
    attachment.IsPrivate = false;
    insert attachment;
    pageRef.setRedirect(true);
    return pageRef;

 }

 
This was selected as the best answer
Brian Cherry FWIBrian Cherry FWI
Thanks for the guidance Karanraj! I added a if(Test.isRunningTest()) to the original class to define those fields. Thanks again!