1

I am using a formula field to retrieve a record from a list in my controller. The retrieved record's id is then used in a wrapper class, within the same controller, to create a new record with the formula matching a lookup record's name, and assigning the record.

Although this works as intended, and there are processes in place that the record actually exists (and is not a duplicate), I suspect that this isn't the most efficient way and in any case is causing the test class to fail:

System.QueryException: List has no rows for assignment to SObject

APEX (snippet)

public with sharing class ReconcileInvoicesController {

public Accounting_Month__c accountingMonth {get;set;}

public ReconcileInvoicesController() {

    accountingMonth = [SELECT id FROM Accounting_Month__c WHERE name = :currentRecord.zAccountingMonth__c LIMIT 1];

}

public void processSelected() {
    selectedDeliveryNotes = new List<Delivery_Note__c>();

    List<Remittance_Advice_Line_Item__c> remAdLineItemsTobeInserted = new List<Remittance_Advice_Line_Item__c>();
        for(wrapDeliveryNote wrapDeliveryNoteObj : wrapDeliveryNoteList) {
            if(wrapDeliveryNoteObj.selected == true) {
                selectedDeliveryNotes.add(wrapDeliveryNoteObj.dn);

                Remittance_Advice_Line_Item__c newRemItem = new Remittance_Advice_Line_Item__c();

                newRemItem.Accounting_Month__c = accountingMonth.ID;

                remAdLineItemsTobeInserted.add(newRemItem);
            }
        }
        if(remAdLineItemsTobeInserted.size() > 0){
            insert remAdLineItemsTobeInserted;
        }
    update selectedDeliveryNotes;
}
}

TEST

@isTest
public class TestReconcileInvoicesController {
    public static testMethod void TestReconcile(){

        string dateString = '2018 - June';
        date dateD = Date.newInstance(2018, 6, 1);

        Accounting_Month__c newAccMon = new Accounting_Month__c(name = dateString);
        insert newAccMon;
        Delivery_Note_Line_Item__c newDNLI = new Delivery_Note_Line_Item__c(
            delivery_Note__c = newDelNote.Id,Order_Line_Item__c = newOrdItem.Id,Quantity_Picked__c = 2,Accounting_Month__c = newAccMon.id);insert newDNLI;
        Remittance_Advice__c newRA = new Remittance_Advice__c(Bank_Statement__c = newBS.id,Account__c = newAcc.id);Insert newRA;

        PageReference pref = Page.ReconcileInvoices;
        pref.getParameters().put('id', newRA.Id);
        Test.setCurrentPage(pref);

        test.startTest();
        ReconcileInvoicesController cont = new ReconcileInvoicesController();

        cont.CurrentRecordDetail = [SELECT id,name,Account__r.name,Account__r.id,AccountId__c FROM Remittance_Advice__c WHERE id = :newRA.Id LIMIT 1];
        cont.accountingMonth = [SELECT id, name FROM Accounting_Month__c WHERE name = '2018 - June' LIMIT 1];

        ReconcileInvoicesController.wrapDeliveryNote delNoteList = new ReconcileInvoicesController.wrapDeliveryNote(newDelNote);

        Delivery_Note_Line_Item__c newDelNoteLineItem1 = new Delivery_Note_Line_Item__c(
            Delivery_Note__c = newDelNote.Id,Quantity_Picked__c = 10,Order_Line_Item__c = newOrdItem.id,Accounting_Month__c = cont.accountingMonth.id);

        test.stopTest();
    }
}
2

I would assume that your code is failing on this line:

accountingMonth = [SELECT id FROM Accounting_Month__c WHERE name = :currentRecord.zAccountingMonth__c LIMIT 1];

And the reason here is that you are always assuming that there will be at least one record returned.

But what if there’s no record? That’s when this code will fail with the exception you have mentioned.

In order to make sure that your code does not fail in absence of a record, you should still use a List<Sobject> notion, and then utilize it elsewhere in the code.

So your approach should look like something as below:

List<Accounting_Month__c> aList = [SELECT id FROM Accounting_Month__c WHERE name = :currentRecord.zAccountingMonth__c LIMIT 1];

Accounting_Month__c aRec;

if(aList.size()>0) {
    aRec = aList.get(0);
}

if(aRec != null) {
    .. rest of my logic ..
}
7
  • Where you have entered "rest of my logic" - how do I write "return aRec ID" to use later in the wrapper class? Oct 24 '18 at 2:06
  • You can utilize the same variable that you have declared on your class. So instead of aRec, you can use your existing variable accountingMonth. And then elsewhere in your class, just check if that’s not null before performing any other operation.
    – Jayant Das
    Oct 24 '18 at 2:12
  • Great, thanks for this. I have one final question. I have added the original query (accountingMonth = [SELECT...) if aRec != NULL, and it works, can you see an issue with doing this? Oct 24 '18 at 2:25
  • Didn’t quite follow it. If you are using accountingMonth as originally posted, it will still throw error in case of no records.
    – Jayant Das
    Oct 24 '18 at 2:29
  • This is what i have done - if(aRec != null) { accountingMonth = [SELECT id FROM Accounting_Month__c WHERE name = :currentRecord.zAccountingMonth__c LIMIT 1]; } Oct 24 '18 at 2:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.