1

I wrote three soql queries in test class

   static testMethod void test_DoGet() {
            RestRequest req = new RestRequest(); 
            RestResponse res = new RestResponse();

            User u = [select id,Lastname,ContactId from user where Contactid != null limit 1]; 
            Contact con = [select id,Lastname,AccountId from contact where id=:u.Contactid];
            Account acc = [select id,name from account where id=:con.AccountID];

            req.requestURI='/services/apexrest/dummy';
            req.httpMethod = 'GET';
            RestContext.request = req;
            RestContext.response = res;            
       }
  }

For the User query, it is returning the user. But for the Account and Contact queries, it is showing System.QueryException: List has no rows for assignment to SObject. I checked in my salesforce edition and it contains many users, Accounts and with contacts.

I tried the above queries like the following.

User u = [select id,Lastname,ContactId from user limit 1]; 
Contact con = [select id,Lastname,AccountId from contact limit 1 ];
Account acc = [select id,name from account limit 1];

Even though it is showing the same error. If these queries is not covered, then i could not complete total coverage.

0

2 Answers 2

6

You have to create your actual test data, I know SeeAllTestData worked but do not do that.

https://developer.salesforce.com/page/An_Introduction_to_Apex_Code_Test_Methods http://www.laceysnr.com/seealldata-why-i-think-you-shouldnt-use/

One reason to not use SeeAllData, lets say your deploying into production. Users are currently inside the org and they are updating accounts. Now when you're trying to deploy the change set the test code runs and by some chance you may also use that account the user is updating, tests will now fail because of row locking and your dead in the water because you're accessing live production data for testing.

Account acc = new Account();
acc.Name = 'Test Name;
insert acc;

Contact con = new Contact();
con.LastName = 'Last Name';
con.AccountID = acc.ID;
insert con;

User u = new User();
u.Lastname = 'Test Name';
u.ContactID = con.ID;
insert u;
2
  • This is the best practice answer! Relying on real data will likely cause tests to fail and prevent deployments.
    – Girbot
    Feb 11, 2017 at 7:57
  • Yes, It's better to avoid using SeeAllData=true where as it gives access a to data in data in organisation which is have permission and which doesn't have permission to users.
    – KS Kumaar
    Feb 13, 2017 at 5:40
2

I would like to reiterate the answer I posted on Why Are Data Silos Important in Unit Tests? There are many compelling reasons why you should not use SeeAllData=true, and I recommend you read through all the posted answers for some perspective, even if you decide that you would rather go the "easy" route. (It may be the easier route now, but it incurs notable technical debt in the long term.)

The Hammer Execution team explicitly asks us to use data silos in our tests (emphasis mine):

Our Commitment To You

This complex juggling act happens three times a year. We make a commitment to you that your customizations will continue to run as you expect, no matter how much we do to change the system. In all my years of being in enterprise software, I have never heard of such a commitment. I’ve never heard of such a smooth upgrade path: you go to bed on Friday, you wake up Saturday, and your system has been upgraded. I still have flashbacks to lenghty, painful upgrade projects for other companies I have worked for – those were never easy times. To save you from these flashbacks, we do the complex ballet described here (which still makes it sound easier than it is) three times a year.

You can help us fulfill this commitment by using data silo. Tests that utilize the new data silo paradigm (seeAllData=false) create their own data, and don’t actually need access to the production data stores. These tests are much faster for us to run, and much more reliable. We don’t need to worry about reading your debug statements, because they’re outputting fake data. We don’t need to worry about having a copy of your production data, because data silo tests do not rely on that data to succeed. Org-independent tests make The Hammer smile.

So you are actually making it more difficult for Salesforce to support you when you use SeeAllData=true. It should be a last resort.


As for why you see these two queries fail where the first succeeds, see:

Isolation of Test Data from Organization Data in Unit Tests

Starting with Apex code saved using Salesforce 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

Whenever possible, you should create test data for each test. You can disable this restriction by annotating your test class or test method with the IsTest(SeeAllData=true) annotation.

Again, Salesforce itself recommends you do not use this annotation except as a last resort.

They do so again in How to Write Good Unit Tests:

Your unit tests should always create their own test data to execute against. That way, you can be confident that your tests aren’t dependent upon the state of a particular environment and will be repeatable even if they are executed in a different environment from which they were written.

And again in Testing Best Practices:

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

You must log in to answer this question.

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