Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

A fresher question.

As per the Apex guide online,

https://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#CSHID=apex_testing.htm|StartTopic=Content%2Fapex_testing.htm|SkinName=webhelp

the following is a test factory class

@isTest
                    public class TestDataFactory {
    public static void createTestRecords(Integer numAccts, Integer numContactsPerAcct) {
        List<Account> accts = new List<Account>();

        for(Integer i=0;i<numAccts;i++) {
            Account a = new Account(Name='TestAccount' + i);
            accts.add(a);
        }
        insert accts;

        for (Integer j=0;j<numAccts;j++) {
            Account acct = accts[j];
            List<Contact> cons = new List<Contact>();
            // For each account just inserted, add contacts            for (Integer k=numContactsPerAcct*j;k<numContactsPerAcct*(j+1);k++) {
                cons.add(new Contact(firstname='Test'+k,lastname='Test'+k,AccountId=acct.Id));
            }
            insert cons;
        }
    }
}

This test factory class from above has one sole purpose of creating generic test data and can be called from other test classes like below.

@isTest
                    private class MyTestClass {
    static testmethod void test1() {
        TestDataFactory.createTestRecords(5,3); ///QUESTION
        // Run some tests
    }
}

My question is at "QUESTION" indicated line above. The "TestDataFactory.createTestRecords()" does not return any data as indicated by "void" in its method definition. Then how "MyTestClass.test1()" will be able to obtain and test the data generated by the utility class ?

Can someone throw light on this ?

share|improve this question

2 Answers 2

up vote 2 down vote accepted

The createTestRecords method commits data to the database using insert.

The records that have been inserted can be retrieved using SOQL:

List<Account> accounts = [SELECT Name FROM Account]; // Will bring back the created accounts
List<Contact> contacts = [SELECT FirstName, LastName FROM Contact]; // Will bring back the created contacts

Personally I prefer to return the records I create in these types of methods as it means I have access to the inserted records (and their Id) without needing the query the database:

public static List<Account> createTestAccounts(Integer numAccts) 
{
    List<Account> accts = new List<Account>();

    for(Integer i = 0; i < numAccts; i++) 
    {
        Account a = new Account(Name = 'TestAccount' + i);
        accts.add(a);
    }

    insert accts;
    return accts;
}
share|improve this answer

In general, test methods only see data that is inserted as part of the test method running. So your test could rely on only the number of Accounts and Contacts passed in to the test method to be present and base its assertions on those numbers.

But it is often useful to be able to reference the inserted data and when multiple objects are involved it is cleaner to use a class to hold those references rather than to try to return them from a method (or have to requery them). This is how that code would look:

@isTest
private class MyTest {
    class Fixture {
        Account[] accounts = new Account[] {};
        Contact[] contacts = new Contact[] {};
        Fixture(Integer numAccts, Integer numContactsPerAcct) {
            for(Integer i = 0; i < numAccts; i++) {
                accounts.add(new Account(Name = 'TestAccount' + i));
            }
            insert accounts;
            for (Integer i = 0; i < numAccts; i++) {
                for (Integer j = numContactsPerAcct * i; j < numContactsPerAcct * (i + 1); j++) {
                    contacts.add(new Contact(
                        FirstName = 'Test' + j,
                        LastName = 'Test' + j,
                        AccountId = accounts[i].Id
                        ));
                }
            }
            insert contacts;
        }
    }
    @isTest
    static void test() {
        Fixture f = new Fixture();
        // Use f.accounts to reference the Accounts as needed
        // Use f.contacts to reference the Contacts as needed
    }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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