0

The line inside the loop in the following code is reported as having no test coverage. This is corroborated by other code that uses the set not having test coverage either.

Previously I was not using SOQL directly, but was using the equivalent methods to get all records in the table (Sobject.getAll() and related) with the same results.

SSCCE:

private static Set<Id> getObjectIds() {
  Set<Id> result = new Set<Id>();
  for (MyTable t : [SELECT Id FROM MyTable]) {
    result.add(t.Id); // This line has no test coverage.
  }
  return result;
}

However, if I execute the following SOQL manually against the same org (Force.com IDE), it returns results.

[SELECT Id FROM MyTable]

What can cause this?

P.S. - I should probably use MyTable.getAll().keySet() but again, that returns an empty set which brings me right back to this question.

Also, we can rule out security since the test user should be able to see pretty much everything anyway and the data in this table is readable by any user.

1 Answer 1

10

Test methods do not have access to pre-existing data in your Org unless you use @IsTest(SeeAllData=true). I would not recommend this though as if you are dependant on certain data being available then your tests may not passed when moved to another Org.

To fix this you need to create some data within your tests, e.g.:

MyTable testMyTable = new MyTable();
insert testMyTable;

This also makes it easier for you to write your asserts as you know exactly what data you should be testing against rather than relying on the correct data being in the Org you are testing on, e.g.:

MyTable testMyTable = new MyTable();
testMyTable.MyField = 'Test';
insert testMyTable;

System.assertEquals('Test', testMyTable.MyField);

The documentation covers this here.

Starting with Apex code saved using Salesforce.com API version 24.0 and later, test methods don’t have access by default to pre-existing data in the organization, such as standard objects, custom objects, and custom settings data, and can only access data that they create. However, objects that are used to manage your organization or metadata objects can still be accessed in your tests such as:

  • User
  • Profile
  • Organization
  • AsyncApexJob
  • CronTrigger
  • RecordType
  • ApexClass
  • ApexTrigger
  • ApexComponent
  • ApexPage
5
  • Could you add a line or two that inserting the data also makes it simpler to write asserts too? Also the mention of getAll suggests the question is about custom setting data.
    – Keith C
    Mar 24, 2014 at 17:37
  • Then why would this test be able to see a preexisting test user? While I agree that a test should set up its own data to ensure portability, in this case we decided to use a specific user which is already set up correctly and exists in all orgs.
    – user6861
    Mar 24, 2014 at 17:41
  • @JohnGaughan As noted in the docs (and my answer) User is one of the objects that is available to you in tests. Although I would recommend still creating User records within your tests rather than relying on them being present in the org. Mar 24, 2014 at 17:41
  • Got it, sorry I am a little slow today.
    – user6861
    Mar 24, 2014 at 17:49
  • @KeithC No problem. Thanks for the advice on improving my answer. Mar 24, 2014 at 19:10

You must log in to answer this question.