13

I am currently programming a trigger on Opportunities.

I created a test class for this and in my Sandbox I created an account, contact and opportunity. When I try to reference them

Opportunity Opp = [SELECT id from Opportunity where name = 'Test1']; 

and then start my

Test.startTest();
        Opp.StageName = 'PO in (100%)'; 
        update Opp; 
       Test.stopTest();

It just errors and shows that Opp returns 0 rows. However when I paste my first bit of code in 'Execute Anonymous' it returns a row and the correct info.

Does this mean I have to create an account, contact, quote and all necessary fields in my test class?

5 Answers 5

13

Do not use existing data. It is a terrible practice for it and there is almost never a need to do it. Using existing data will cause serious issues whenever you create a new sandbox or attempt to move any code to a different organization.

It is considered a very bad practice. There is a reason Salesforce removed the ability to access data from the system by default in version 24. Problems like - UNABLE_TO_LOCK_ROW error while running all apex test classes - pop up when running asynchronous tests. Avoid those problems now and write the tests with the best practice right out the gate.

Here is some good documentation on writing unit tests. There is also Isolation of Test Data from Organization Data in Unit Tests.

EDIT: A common practice my coworkers and I have used is creating a TestUtils class and using that class to create the data model. That would allow you to do something like:

@isTest
public class TestUtils{
    public static Account getAccount(){
        Account acc = new Account(Name = 'Account');
        insert acc;
        return acc;
    }
}

then from your test method:

@isTest
public class TestClass{
    static testMethod void myTest() {
        Account acc = TestUtils.getAccount();
    }
}

This will generate an account, insert it into the DB, and then return it to be used in the test. This can then be reused around the system.

8
  • Thanks Jesse, I agree with your statement, however I am using a sandbox that has 0 data. Then I added data manually. So my sandbox only has 1 account, 1 contact, etc. Woud seealldata at this point be useful and or ok?
    – jnoel10
    Feb 15, 2013 at 18:41
  • No because when you deploy to production these tests must run and they have to pass or Salesforce will not deploy your code. The only way to get code into production is to have all of your tests run, all of your tests pass, have a minimum of 75% total code coverage, and at least 1% on every trigger. Feb 15, 2013 at 18:43
  • ahhhhhh good point. Let the headache begin !
    – jnoel10
    Feb 15, 2013 at 18:45
  • I added some more info to my post to kind of give you a decent idea how to do it (or at least how my coworkers and myself do it). Feb 15, 2013 at 18:48
  • Great idea Jesse, I plan on doing the same, The only problem is there are so many required fields on the system that I need to create multiple objects. Like Contacts associated to the opportunity and so on.. I figured it would be simpler to jut create them outside of coding.
    – jnoel10
    Feb 15, 2013 at 18:58
18

Adding to Rao and user31's responses. . . by design, test classes do not have access to your org's data unless you explicitly set SeeAllData=true. There are multiple problems with relying upon pre-existing data:

  1. You have no way of guaranteeing the data you expect will exist
  2. You have no way of guaranteeing the data you retrieve will accurately run through your tests

By setting up your own test data you:

  1. You remove problems with locks
  2. Know exactly what is present with regards to good and bad data
  3. Can help improve your testing by having proper edge cases tested
  4. Remove dependencies outside of your control
9

If you are absolutely sure there will be sample data in the org (eg this runs in a Trial), you can use the @isTest(SeeAllData=true) annotation... but you probably shouldn't!

0
3

The highest recommendation and best practice is to create data on the flow and not to use Existing data

Disadvantages of using Seealldata: I have seen lock errors due to test class trying to access the data during deployments/ user trying to modify a record( Which was assumed to be a test data in the test class)

Always stick on to create that update, but scenarios like Profile, Recordtypes are some cases where you can query and not have to create the record.

Update for using recordtype in test class : Check out the code below without using a actual query you can pull the recordtype info

check this blog : http://salesforceapexcodecorner.blogspot.com/2012/03/record-type-for-crating-test-class-data.html

public class seealldatatest{
list<account> acc{get;set;}
public seealldatatest(){
acc = [select id,recordtype.name from account limit 10];
}
public void testingdata(){
    for(account a: acc){
        if(a.recordtype.name == 'Japan'){
        // do something
        }
    }
}
@Istest
public static void testmeth1(){
Schema.DescribeSObjectResult cfrSchema = Schema.SObjectType.Account; 
Map<String,Schema.RecordTypeInfo> AccountRecordTypeInfo = cfrSchema.getRecordTypeInfosByName();  
Account Acc = new Account(Name='test',recordtypeid=AccountRecordTypeInfo .get('Japan').getRecordTypeId());
insert Acc;
seealldatatest s_test = new seealldatatest();
s_test.testingdata();
}
}
2
  • Thanks rao, I am having the issue with the Recordtype, So i need to do the see-all in order to query my recordtype?
    – jnoel10
    Feb 15, 2013 at 18:36
  • No, RecordTypes are available. It's actual data (your records) that are not available by default.
    – Mike Chale
    Feb 15, 2013 at 18:58
0

It is definitely best practice to not use org data for testing purposes. Except for those situations where you have to -- Pricebooks being the primary culprit. However, if you are not using Pricebooks, then you should avoid using org data like the plague.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .