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.

I have multiple Test classes that has duplicate code. One of the methods is to create opportunity records. Can I create a separate class that does this by itself and reference it from the Test classes?

share|improve this question

4 Answers 4

up vote 7 down vote accepted

Short answer:

YES!

Long Answer:

It's the same as with any reusable code, just create another class and add your method:

@IsTest
public with sharing class TestUtils
{
  public static void CreateOppty()
  {
    // create and insert an oppty etc.
  }
}

You can then call this method from any of your other test methods to setup data:

public static testmethod void SomeTest()
{
  TestUtils.CreateOppty();
  Test.StartTest();
  // do testing
}

There's an example in the documentation too.

share|improve this answer

You can definitely do this, I always do this for my frequently used objects. You can just create a standard public class and then call it from your test classes. Because it gets called a lot, the test coverage for the class is generally going to be near 100%.

I typically do the following:

@isTest
public class TestObjects {

// public Lists of freq used objects eg account
public List<Account> accList;

// methods to create a new instance
public void addNewAccount(Account a) {
    if (accList == null) {accList = new List<Account>();}
    accList.add(a);
}

public static Account newAccountFromData (String accName, Id recType) {
    Account a = new Account(Name = accName, RecordTypeId = recType);
    return a;
}

Then in your test class,

TestObjects t = new TestObjects();
t.addNewAccount(TestObjects.newAccountFromData('Test acc'));

And reference the account as

Account thisacct = t.accList[0];

Variations are obviously possible, this is a start...

share|improve this answer
1  
If you annotate your TestObjects class with @isTest you don't need to cover it. It would be similar to having a private utility method in a test class itself, not needing coverage. –  Peter Knolle Feb 27 '13 at 1:53
    
Very true Peter, have amended the answer above - thanks! –  Stephen B Feb 27 '13 at 7:04

Just an addition to LaceySnr's answer. It was not available at the time of question and answers but was added in Spring '15 release. It is pretty cool and in my opinion worth mentioning.

It's called Test Setup Methods.

You can create a seperate method that creates data for all test methods before they are run - they are inserted into database and can be fetched later in each method. So if you need to create a lot of test data around opportunities (many DML operations) it might be more efficient to create them this way. Changes made to each record in any test method are not affecting other test methods - they are made just in scope of that test method.

To use this approach you need to implement @testSetup

@isTest
private class YourTestClass {
    @testSetup static void dataSetup() {
        // Create Opportunities or some other data
        // You can call some static methods here as well
        createOpps();
        createSomethingElse();
    }

    private static void createOpps() {
    }

    @isTest static void testMethod1() {
        // you can use created data here by fetching it from DB
    }
}

Documentation can be found here: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_testsetup_using.htm

share|improve this answer

I use a slightly different approch than LaceySnr. Instead of using static records my creator classes return them as sObject lists. Depending on your needs of course. If you want different test classes use the same data, then LaceySnr's answer is the way to go for. If not and you want to edit the records created by the creator class slightly or you simply want your insert statement within your test class, you could do the following:

public class AccCreator
{
    public static list<sObject> getAccs(Ineger numRecords, String prefix)
    {
        list<Account> accs = new list<Account>();

        for ( Integer i = 0; i < numRecords; i++ )
        {
            Account acc = new Account();
            // If using duplicate rules, do not run them for Accs containing "test"
            acc.Name = prefix + ‘_Test_’ + i;
            // Populate fields to your needs
        }
        return accs;
    }
}

Dependencies like Record Type IDs would have to be set up as static variable/collection beforehand if you use them.

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.