1

I am fairly new to Salesforce, I have a trigger which requires a test method for it to meet its code coverage.

I am getting errors in the test class stating

Error: Compile Error: Illegal assignment from LIST to Id at line 10 column 9

Trigger: PopulateHolidaysFromObject

trigger PopulateHolidaysFromObject on Opportunity (before insert,before update) {

    List<Holiday__c> HolidayList = [SELECT Name,Holiday_Date__c FROM Holiday__c];

    for(Opportunity opp : Trigger.new){

        HolidayClass holidayclass= new HolidayClass();
        opp.No_Of_Survey_Holidays__c = holidayclass.NoOfHolidays(opp.Site_Visit_Survey_Request_Date__c,opp.Site_Visit_Survey_Completed_Date__c,HolidayList);
        system.debug(opp.No_Of_Survey_Holidays__c);
        opp.No_Of_Report_Holidays__c = holidayclass.NoOfHolidays(opp.Site_Visit_Survey_Request_Date__c,opp.Scope_and_Cost_Report_Completed_Date__c,HolidayList);
        system.debug(opp.No_Of_Report_Holidays__c);        
    }
}

Test Class:

@isTest
private class TerminateServiceTest
{
    static testMethod void testTermination() 
    {
        // Setup the invoice line record
        Invoice_Line__c inv = new Invoice_Line__c();
        inv.Invoicing_Output__c = 'New Invoice';
        inv.Installation_Date__c = system.today();
        inv.Invoicing_Output__c = [SELECT id FROM Invoicing_Output__c];
        insert inv;

        // Setup service instance record
        Service_Instance__c si = new Service_Instance__c();
        si.Opportunity__c = 'New Invoice';
        si.Account__c = [SELECT id FROM Account];
        si.Airport__c = 'GAT';
        si.Contract__c = [SELECT id FROM Contract__c];
        si.Local_Service__c = [SELECT id FROM Local_Service__c];        
        si.Quantity__c = 10;
        si.Service_Start_Date__c = system.today();
        si.Service_End_Date__c = date.newInstance(2016, 8, 11);      
        si.Address__c = [SELECT id FROM Address__c];
        insert si;

        test.startTest();

        inv.Invoicing_Output__c = 'Termination Invoice';
        update inv;

        Service_Instance__c lTest = [SELECT Id, isActive__c FROM Service_Instance__c WHERE Id=:inv.Id];
        system.assertEquals(false, lTest.isActive__c );

        test.stopTest();
    }
}

Can you help me to see what is causing this error?

0

You are trying to set a lookup field (inv.Invoicing_Output__c) which is an ID, to a SOQL statement that returns a list of objects.

If you want to SOQL for a particular value you would do something like this.

Id myIOId = [SELECT id FROM Invoicing_Output__c].[0].Id;
inv.Invoicing_Output__c = myIOId;

This however is going to come up empty as you have not yet created an Invoicing_Output__c record. You should first create that, insert it, and then set it on the Invoice_Line__c record.

//Setup the Invoicing Output record
Invoicing_Output__c invOP = new Invoicing_Output__c();
//Set the attributes you need
insert invOP;

// Setup the invoice line record
Invoice_Line__c inv = new Invoice_Line__c();
inv.Invoicing_Output__c = 'New Invoice';
inv.Installation_Date__c = system.today();
inv.Invoicing_Output__c = invOP.Id;
insert inv;
| improve this answer | |
0
inv.Invoicing_Output__c = [SELECT id FROM Invoicing_Output__c];

inv.Invoicing_Output__c is expecting a single record ID, whereas [SELECT id FROM Invoicing_Output__c] is returning a list of SObject records. Try this:

List<Invoicing_Output__c> invOutList = new List<Invoicing_Output__c>([SELECT id FROM Invoicing_Output__c]);

if (!invOutList.isEmpty()) {

    inv.Invoicing_Output__c = invOutList[0].Id;
}

And so on for the rest of the lookup / master details fields you need to populate.

Not a perfect solution as you won't guarantee what record is being returned & is at the 0th position in the list, but it solves the problem at hand.

| improve this answer | |
0

The error is telling you that you are assigning a list (of zero or more objects) returned by the query in the square brackets to a field that should hold just an ID value. Object relationships are setup via (foreign key) ID values where the ID of a parent object is stored in an ID field of a child object that is named (by default) the same as the parent object type.

The best (and default) pattern in tests is to create all the objects you need within the test. Code something like this would do that for the first example and you would need to copy the same pattern for further four cases immediately below:

Invoicing_Output__c io = new Invoicing_Output__c(...);
insert io;

Invoice_Line__c inv = new Invoice_Line__c();
inv.Invoicing_Output__c = 'New Invoice';
inv.Installation_Date__c = system.today();
inv.Invoicing_Output__c = io.Id;
insert inv;

But looking at your trigger, the trigger will not fire unless you insert or update an Opportunity so your test will have to do that as well to get the trigger to run. At first sight the trigger and test don't look very related (holidays surveys in the trigger and invoices and services in the test).

Your trigger includes a query of all Holiday__c objects which unless you can guarantee that the maximum number of these is limited is dangerous. A more common pattern is to gather some values from the object that the trigger is firing on to then use to limit the number of objects queried via a where clause and so avoid hitting governor limits.

| improve this answer | |

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.