Why isn’t a SOQL query of mine populating a list in an Apex test class?

Why does my taskOpp query below not return any records when I run this test? The query works fine in Workbench and my taskRT query works fine in both my code and in Workbench.

public class LinkCampaign2Task_test {
  static testMethod void validateOppTaskCampaignId(){
    List <Opportunity> taskOpp = [SELECT CampaignId,Id FROM Opportunity WHERE CampaignId != ''];
    List <RecordType> taskRT = [SELECT Id FROM RecordType WHERE Name = 'Outbound Call'];


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You need to create Opportunities in your test class. When you run test classes its like a blank database. You need to create a Campaign then link an opportunity to it.

Campaign camp = new Campaign();
insert camp;

insert new Opportunity(CampaignId = camp.Id);

EDIT: Like others have said, you can use the @seealldata to see existing data in your org, but it is highly suggested to NOT do this. Instead it is better to create your test data in the code for tests (or a static resource import).

Method 2

In your test example you have not populated any data for the test to run against. It is best practice to create test data for each unit test, them validate your code via asserts. Thankfully you do not have to worry about removing the data as Salesforce properly tracks and deletes the test objects for you at the end of each test method.

Additionally, while it is possible for you to access the org’s real data within a unit test, that is bad practice. However, there are a few cases where that is required. Thankfully most of those cases are reported by the test runner.

Method 3

As of API v.24 or later, data in your organization is isolated from tests. There are two ways to address this. You can change your tests to (SeeAllData=true), an annotation of @isTest or you can create your context data in your test prior to running a SOQL. I recommend creating your test data within your tests as a best practice because you can more tightly control your test scenario and you don’t have to rely on instance data. Relying on instance data makes your code less portable because your tests rely on data + code logic to function correctly and only certain types of sandboxes will move your data, and none will keep data in sync with production.

See this article on Isolation of Test Data from the documentation.

Method 4

@jwolf is correct, but I would like to add that you should not just throw in the SeeAllData tag as this is not best practice. For a test method, you first need to create your own data.

In the code below, your query will now return a list containing your newly created opportunity.

public class LinkCampaign2Task_test {

  static testMethod void validateOppTaskCampaignId(){

    Opportunity opp1 = new Opportunity();
    //Add your fields
    insert opp1;

    List <Opportunity> taskOpp = [SELECT CampaignId,Id FROM Opportunity WHERE CampaignId != ''];
    List <RecordType> taskRT = [SELECT Id FROM RecordType WHERE Name = 'Outbound Call'];


I would take a look at some documentation around test data. Here are some good ones




Method 5

Test methods cannot access any non setup data unless you use the @seeAllData annotation. See the “Isolation of Test Data from Organization Data in Unit Tests” article in the apex developer guide. Here’s a link.

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x