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
D J RobertsD J Roberts 

TestDataFactory not returning results when run from test method

Hey everyone, 

I'm creating a unit test for updating accounts with a total number of contacts, but I'm trying to do this from my Test Class, "TestDataFactory" (CodeSnippet below). The method that I wrote is called queryAccounts(Integer qLimit); 

When I execute the code in anonymously, it will return the expected result, but these values are not being returned to the test class when I call the TestDataFactory.queryAccounts(1); 

Any idea what the issue is? 
AccountProcessorTest() Code Snippet: 
@isTest
private class AccountProcessorTest {

    @isTest public static void singleAccountUpdate() {
      //Get test data for testing
      Test.startTest();
        Id[] acctIds = TestDataFactory.queryAccounts(1); 
        System.debug('Results = ' +TestDataFactory.queryAccounts(1)); 
      	List<Contact> cons = [SELECT Id, AccountId FROM Contact WHERE AccountId IN: acctIds];
        integer numOfContacts = cons.size();
        System.debug('acctIds = ' + acctIds.size()); 
       //test the update of the Contacts record count on Accounts.
        
        Account acctUpdate = new Account(Id = acctIds[0], Number_of_Contacts__c = numOfContacts); 
        update acctUpdate; 
        Test.StopTest(); 
    }
    
    @isTest static void multipleAccountUpdate(){
        //Test multiple accounts. 
    }
}



TestDataFactory() Code Snippet: 
 
@isTest
public class TestDataFactory {
    public static List<Account> createAccountsWithOpps (Integer numAccts, Integer numOppsPerAcct){
        List<Account> accts = new List<Account>(); 
        for(Integer i=0; i<numAccts;i++){
            
            Account a = new Account(Name = 'TestAccount' + i); //assigning incremental name
            accts.add(a); //Adds accounts to accts list. 
        }
        
        insert accts; 
        
        List<Opportunity> opps = new List<Opportunity>(); 
        for(Integer j = 0; j<numAccts; j++){
            Account acct = accts[j]; 
            for (Integer k=0; k<numOppsPerAcct; k++){
            opps.add(new Opportunity(Name = acct.Name + 'Opportunity ' + k, 
                                           StageName = 'Prospecting',
                                           CloseDate=System.today().addMonths(1),
                                           AccountId=acct.Id));
            }
            
           }
        insert opps; 
        return accts; 
    } 
    public static List<Id> queryAccounts(Integer qLimit){
     List<Id> acctIds = new List<Id>(); 
     List<Account> accts = ([SELECT Id FROM Account LIMIT: qLimit]);   
        for(Account a : accts ){
            system.Debug('The ID is added  '+ a.Id );
            acctIds.add(a.Id);
        }
        system.debug('qLimit = ' + qLimit); 
        return acctIds;
    }
}

 
Best Answer chosen by D J Roberts
ApuroopApuroop
Hey Batman,

You need to either create some test accounts which can be queried in the current context or use the (SeeAllData=true)

The following works good in mine. Try it, I just added seeAllData=true. 
 
@isTest(seeAllData=true)
private class AccountProcessorTest{
    public static testMethod void singleAccountUpdate(){
      //Get test data for testing
      Test.startTest();
        List<Id> acctIds = TestDataFactory.queryAccounts(1); 
        System.debug('Results = ' +TestDataFactory.queryAccounts(1));
        System.debug('Results = ' +acctIds);
        System.debug('acctsIds Size = ' +acctIds.size());
        
      	List<Contact> cons = [SELECT Id, AccountId FROM Contact WHERE AccountId IN: acctIds];
        integer numOfContacts = cons.size();
        System.debug('acctIds = ' + acctIds.size()); 
       //test the update of the Contacts record count on Accounts.
        
        Account acctUpdate = new Account(Id = acctIds[0], Number_of_Contacts__c = numOfContacts); 
        update acctUpdate; 
        Test.StopTest(); 
    }
    
    @isTest static void multipleAccountUpdate(){
        //Test multiple accounts. 
    }
}

I have a question though, why is the TestDataFactory starting with the @isTest annotation. It can be a normal class IMO. :)

All Answers

ApuroopApuroop
Hey Batman,

You need to either create some test accounts which can be queried in the current context or use the (SeeAllData=true)

The following works good in mine. Try it, I just added seeAllData=true. 
 
@isTest(seeAllData=true)
private class AccountProcessorTest{
    public static testMethod void singleAccountUpdate(){
      //Get test data for testing
      Test.startTest();
        List<Id> acctIds = TestDataFactory.queryAccounts(1); 
        System.debug('Results = ' +TestDataFactory.queryAccounts(1));
        System.debug('Results = ' +acctIds);
        System.debug('acctsIds Size = ' +acctIds.size());
        
      	List<Contact> cons = [SELECT Id, AccountId FROM Contact WHERE AccountId IN: acctIds];
        integer numOfContacts = cons.size();
        System.debug('acctIds = ' + acctIds.size()); 
       //test the update of the Contacts record count on Accounts.
        
        Account acctUpdate = new Account(Id = acctIds[0], Number_of_Contacts__c = numOfContacts); 
        update acctUpdate; 
        Test.StopTest(); 
    }
    
    @isTest static void multipleAccountUpdate(){
        //Test multiple accounts. 
    }
}

I have a question though, why is the TestDataFactory starting with the @isTest annotation. It can be a normal class IMO. :)
This was selected as the best answer
D J RobertsD J Roberts
Thanks, Apuroop! 

I thought about using (seeAllData=true) but I was under the impression that this would make a test class actually modify records in the database. Does the parameter only give access to the data, or does it also allow the testClass to modify the data in the org? 

 
ApuroopApuroop
With this thread: https://salesforce.stackexchange.com/questions/53998/test-class-seealldata-true-annotation, with even more confidence I could say the data will be available for the test method/class. It'll not modify any live data.

However, it's always a good practice to create some test records in the test setup method (If it's a big class that you're testing). In your case, when you're using the TestDataFactory.queryAccounts(); method - you could use the seeAllData=true, since it's clearly for querying and you aren't modifying any data. 

Put all the methods which are querying in the test method with the seeAllData=true annotation and then rest without the annotation.
D J RobertsD J Roberts
Thanks a bunch, and for the quick responses. Really appreciate it.