2

I have this class which basicly generates reports:

public class A800DailySFReport {
    Public List<Storage_Unit__c> availableST {get;set;}
    Public List<Quotation__c> renewedQuotation {get;set;}
    Public List<Quotation__c> newQuotation {get;set;}
    Public List<Invoice__c> renewedInvoices {get;set;}
    Public List<Invoice__c> newInvoices {get;set;}
    Public List<Invoice__c> forCollectionInvoices {get;set;}
    Public Integer free {get;set;}
    Public String dte {get;set;}
    public A800DailySFReport(){
             Date d0 = Date.today();
            dte= d0.day()+' - '+d0.month()+' - '+d0.year();
            availableST = [SELECT Name,Tag__c,Level__c,Warehouse__c FROM Storage_Unit__c WHERE Status__c = 'Free' AND Tag__c != 'Outdoor Lot'];
            free = availableST.size();
            renewedQuotation = [SELECT ID,Paid_Invoices__c,Previous_Quotation__c,Quotation_Total__c,Client_Name__c,Name,Status__c,From__c,To__c FROM Quotation__c WHERE Status__c = 'Accepted' AND Paid_Invoices__c > 0  AND Previous_Quotation__c != null ];
            newQuotation = [SELECT ID,Paid_Invoices__c,Previous_Quotation__c,Quotation_Total__c,Client_Name__c,Name,Status__c,From__c,To__c FROM Quotation__c WHERE Status__c = 'Accepted' AND Paid_Invoices__c > 0  AND Previous_Quotation__c = null ];
            Set<ID> idSetforRenewal = new Set<ID>();
            for(Quotation__c temp : renewedQuotation){
                idSetforRenewal.add(temp.ID);
            }
             Set<ID> idSetforNew = new Set<ID>();
            for(Quotation__c temp : newQuotation){
                idSetforNew.add(temp.ID);
            }
            renewedInvoices = [SELECT Client_Name__c,Collected_Amount__c FROM Invoice__c WHERE Quotation__c IN :idSetforRenewal AND Payment_Date__c =:d0];
            newInvoices = [SELECT Client_Name__c,Collected_Amount__c FROM Invoice__c WHERE Quotation__c IN :idSetforNew AND Payment_Date__c =:d0];
            forCollectionInvoices = [SELECT Amount_Due__c,Client_Name__c,Collect_By__c FROM Invoice__c WHERE Expected_Payment_Date__c =:d0 AND Amount_Due__c > 0 AND Collect_By__c = 'Driver'];
        }
}

I need to make a test class for it, but I'm not sure how or where to start. I tried first to insert some records and retrieve them with a SOQL query and put the result in a List<sObject> and compare it with a new instance attribute using System.assertEquals(). My Code:

@isTest public class A800DailySFReportTest {

    @IsTest(SeeAllData=true) public static void positiveTest() {
        Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator']; 
        User u = new User(Alias = 'Mazen', Email='mazen@magna.com', 
             EmailEncodingKey='UTF-8', LastName='Tester', LanguageLocaleKey='en_US', 
             LocaleSidKey='en_US', ProfileId = p.Id, TimeZoneSidKey='America/Los_Angeles', UserName='mazen@magna.com');
        insert u;
        System.runAs(u){
            // SELECT Name,Tag__c,Level__c,Warehouse__c FROM Storage_Unit__c WHERE Status__c = 'Free' AND Tag__c != 'Outdoor Lot'
            Storage_Unit__c storeUnit_1 = new Storage_Unit__c(Name='F1', Status__c = 'Free', Tag__c = 'Somthing else');
            insert storeUnit_1;
            Storage_Unit__c storeUnit_2 = new Storage_Unit__c(Name='F2', Status__c = 'Free', Tag__c = 'Somthing else');
            insert storeUnit_2;
            List<Storage_Unit__c> availableUnits = new List<Storage_Unit__c>();
            for(Integer i = 0; i < 200; i++){
                availableUnits[i].Status__c = 'Free';
                availableUnits[i].Tag__c = 'Somthing else';
            }
            insert availableUnits;


            List<Storage_Unit__c> availableST_tst = [SELECT Name,Tag__c,Level__c,Warehouse__c FROM Storage_Unit__c WHERE Status__c = 'Free' AND Tag__c != 'Outdoor Lot'];

            A800DailySFReport report = new A800DailySFReport();
            System.assert(availableST_tst.size()>0);
            System.assertEquals(availableST_tst, report.availableST, 'Matched');
        }
    }
}

Anyway, when I click run on Force.com IDE it has no errors but the code coverage percent of this class still 0%, is that right? I know that I haven't finished yet of working on the test class and I have to wirte extra methods, byt still. Am I doing it right till now? or somthing wrong? if not plz advice me with any clue or hint.

enter image description here

  • 1
    >>Anyway, when I click run on Force.com IDE it has no errors. Are you running your test? Did it finish with success? – Ilya Lepesh Jul 4 '16 at 20:09
  • Asserting the equality of two List<SObject> is plain foolish. Asserting on their Set<Id> is a much more sensible approach. – Adrian Larson Jul 4 '16 at 20:12
  • @IlyaLepesh Eclipse don't show me my test class in green color either red color, so I don't know! – MAZux Jul 4 '16 at 20:12
  • @AdrianLarson You mean I have to call this: System.assertEquals(availableST_tst.Id, report.availableST.Id, 'Matched'); ? – MAZux Jul 4 '16 at 20:13
  • @MAZux List<SObject> has no property called Id. See my answer for a more appropriate approach. Also check out one of the most popular posts on our exchange which is relevant here. Also, if you run tests through the UI, you might get more helpful information. – Adrian Larson Jul 4 '16 at 20:19
0

Failure Cause

The following lines are going to give you a List index out of bounds error:

List<Storage_Unit__c> availableUnits = new List<Storage_Unit__c>();
for(Integer i = 0; i < 200; i++){
    availableUnits[i].Status__c = 'Free';
    availableUnits[i].Tag__c = 'Somthing else';
}
insert availableUnits;

Since the test fails, it can't give coverage. Change to:

List<Storage_Unit__c> availableUnits = new List<Storage_Unit__c>();
for(Integer i = 0; i < 200; i++)
{
    availableUnits.add(new Storage_Unit__c(Status__c = 'Free', Tag__c = 'Somthing else'));
}
insert availableUnits;

If either of these fields are unique, you may need to add the counter value on the end to avoid error.


Original Advice

I don't know if this answer will solve your question, but I would strongly advise against your approach to comparing List<SObject>. If you simply want to verify that you queried the correct records, much better to use Set<Id>.

Here is a basic example:

static testMethod void testMyConstructor()
{
    // create records

    Test.startTest();
        MyClass instance = new MyClass();
    Test.stopTest();

    Set<Id> expectedRecordIds = new Map<Id, SObject>([SELECT Id FROM MyObject__c]).keySet();
    Set<Id> actualIds = new Map<Id, SObject>(instance.records).keySet();
    system.assertEquals(expectedRecordIds, actualIds, 'message');
}

The reason comparing the List<SObject> directly is a poor idea is that you will only get equality if every field has the same value. If some fields are set in one list and not the other, your assertion will fail. Even fields included by default in the query (e.g. RecordTypeId) can cause this type failure. See also: Using an sObject as a Map key

  • I did what you suggest, but also I still have a 0% code coverage, why is that? any idea? – MAZux Jul 4 '16 at 20:27
  • Simply running your constructor without failure should generate 100%. Either your test failed, your your reporting mechanism is flawed. There are a couple steps you can take for the latter, but can you confirm if the test passed before going down that road? @MAZ – Adrian Larson Jul 4 '16 at 20:30
  • How could I track what's happening? – MAZux Jul 4 '16 at 20:30
  • Just run the tests through the UI... It's very obvious whether the test passes or fails. – Adrian Larson Jul 4 '16 at 20:30
  • I added a picture, I didn't notice the test result of my class. – MAZux Jul 4 '16 at 20:33

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.