2

I'm trying to develop my first test class in our sandbox instance. When running the below test, I am getting no records return from the first query to build accountsList. The test succeeds, but I have 0% code coverage. The trigger works as expected when ran.

My Test Class:

@isTest
private class test_deleteAccountSharesOnUpdate {

static testMethod void updateAccounts() 
{
    Set<String> accountIds = new Set<String>();

    List<Account> accountsList = 
    [
        SELECT Id, Is_Script_Update__c, Description FROM Account
    ];

    Integer i = 0;
    for (Account acct : accountsList)
    {
        if(i > 199)
        {
            break;
        }

        acct.Is_Script_Update__c = True;
        acct.Description = 'Testing at ' + System.now();

        accountIds.add(acct.Id);

        i++;
    }

    test.startTest();

    update accountsList;

    test.stopTest();

    List<Account> updatedAccts = 
    [
        SELECT Id, Is_Script_Update__c, Description
        FROM Account 
        WHERE Id IN : accountIds
    ];

    for(Account acct : updatedAccts)
    {
        System.assertEquals
        (
            'Testing at',
            acct.Description.substring(0,10)
        );
    }
}

}

Trigger I'm trying to test:

trigger deleteAccountSharesOnUpdate on Account (after update) 
{   
Set<String> accountIds = new Set<String>();

// Gather the account Ids being updated
for (Account acct : trigger.new)
{
    // Only remove shares for accounts being updated by data loader.
    // Loader script will insert new shares after this job.
    if(acct.Is_Script_Update__c)
    {
        String terrCode = acct.Territory_Code_String__c;

        if(terrCode != null && terrCode.length() == 5)
        {   
            accountIds.add(acct.id);
        }
    }
}

if(accountIds.size() > 0)
{
    // Remove the shares associated with these accounts
    delete 
    [
        select id 
        from AccountShare 
        where RowCause = 'TerritoryManual' AND 
        AccountId IN : accountIds
    ];

    // Reset flag that indicates this update is from a data loader.
    // Data loader will set this checkbox as true on update.
    // This prevents the trigger on UI update.
    //
    List<Account> accountsList = 
    [
        SELECT Id, Is_Script_Update__c 
        FROM Account 
        WHERE Id IN: accountIds
    ];

    for (Account acct : accountsList)
    {
        acct.Is_Script_Update__c = False;
    }

    update accountsList;
}

}

Degub log shows no rows returned for the first query:

14:47:14.461 (3461430000)|SOQL_EXECUTE_BEGIN|[8]|Aggregations:0|select Id, Is_Script_Update__c, Description from Account 14:47:14.483 (3483545000)|SOQL_EXECUTE_END|[8]|Rows:0

Any help is greatly appreciated!

2 Answers 2

5

This is because Test methods do not have access to your organization data. You need to create the Accounts prior to trying to test the trigger. Try adding this to the top of your test method

Account a = new Account(Name = 'Test Account'); //Make sure to add any fields that are required or included in validation rules to allow for insert
insert a;

Here is a blurb from the Apex testing best practices

Set up test data:

Create the necessary data in test classes, so the tests do not have to rely on data in a particular organization.

Create all test data before calling the starttest method.

Since tests don't commit, you won't need to delete any data.

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_best_practices.htm

2
  • Well, I'm feeling pretty silly. That did it! It's amazing what happens when you follow the rules. Thanks sfdc_ninja!
    – Adam H.
    Commented Feb 4, 2014 at 20:31
  • No prob, glad to help. :) Commented Feb 4, 2014 at 20:38
5

Since Spring '12 test classes are isolated from the data on the server. They are abstracted to only see data they create (with exceptions like user, profile, etc). To enable the class to see all you need to use @isTest(SeeAllData=true).

I highly recommend you DO NOT use that method though. The proper way to do this is to create the test data at the top of your test class (or use a static method for building it in multiple tests). After your test data is created then you should call Test.startTest() to reset the governor limits, and Test.stopTest() at the end of the test.

Here is a great read from Matt Lacey (force.com MVP) on why you should not use SeeAllData=true.

http://www.laceysnr.com/2012/04/seealldata-why-i-think-you-shouldnt-use.html

2
  • 1
    Worth noting Spring '12 started with API 23. Anything using 23 and above will not see the data in your org without the annotation.
    – drakored
    Commented Feb 4, 2014 at 20:04
  • SeeAllData = SAD -- it's a bad, bad practice only to be used under dire circumstances. Also it's worth checking out a relatively new feature [Test.LoadData(developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… that allows you to create test data from a CSV file that you've loaded as a static resource. Commented May 5, 2016 at 11:30

You must log in to answer this question.

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