function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Jason Liu 7Jason Liu 7 

Test Class question

Yo Team,

I'm new to the apex development and really confuse how to use contructor in the Class. So I look other Sr.developer's code and mimic the apex class, I'm so lucky that works. But turn to Test, I kind stuck there. Following is my Apex class and test class(not working) I created, I truely appriate that if anyone could give me some advises.

Apex Class:

public class HouseholdpageController {
    List<Account> accounts;
    public Lead currentlead{get;set;}
    public ApexPages.StandardSetController stdCntrlr {get; set;}
    public HouseholdpageController (ApexPages.StandardController controller)
  {     
    this.currentlead = (Lead)controller.getRecord(); 
    }
    public List<Account> getAccounts(){
        currentlead = [ Select Id, Equifax_Household_ID__c from Lead where Id =: ApexPages.currentPage().getParameters().get('Id') ];
        if(currentlead.Equifax_Household_ID__c != null) accounts = [select name, Loan_Balance__c, Deposit_Balance__c from account where Equifax_Household_ID__c =: currentlead.Equifax_Household_ID__c];
     
        return accounts;
    }

}


Test Class(Error:System.QueryException: List has no rows for assignment to SObject)
/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 *
 * Unit tests are class methods that verify whether a particular piece
 * of code is working properly. Unit test methods take no arguments,
 * commit no data to the database, and are flagged with the testMethod
 * keyword in the method definition.
 *
 * All test methods in an organization are executed whenever Apex code is deployed
 * to a production organization to confirm correctness, ensure code
 * coverage, and prevent regressions. All Apex classes are
 * required to have at least 75% code coverage in order to be deployed
 * to a production organization. In addition, all triggers must have some code coverage.
 * 
 * The @isTest class annotation indicates this class only contains test
 * methods. Classes defined with the @isTest annotation do not count against
 * the organization size limit for all Apex scripts.
 *
 * See the Apex Language Reference for more information about Testing and Code Coverage.
 */
@isTest
private class HouseholdpageControllerTest {
    static testMethod void UnitTest() {
        RecordType rt = [SELECT Id,Name FROM RecordType WHERE SobjectType='Account' AND Name = 'Person Account'];   
        RecordType lead = [select Id from RecordType where DeveloperName = 'Relationship_Expansion_Leads']; 
        
        Profile p = [
            select Id
            from Profile
            where Name = 'System Administrator'
        ];
        
        User u = new User(
            Alias = 'standt',
            Email = 'standarduser@testorg.com',
            EmailEncodingKey = 'UTF-8',
            LastName = 'Testing',
            LanguageLocaleKey = 'en_US',
            LocaleSidKey = 'en_US',
            ProfileId = p.Id,
            TimeZoneSidKey = 'America/Los_Angeles',
            UserName='1512434@dfe1.COM'
        );
        
        Account testAccount1 = new Account(       
          FirstName='Test Description', 
          LastName='Test Last Name',
          RecordTypeId = rt.Id,
        Equifax_Household_ID__c = '123',
        Loan_Balance__c = 321,
        Deposit_Balance__c  = 456
        );
        Lead testLead1 = new Lead(
            LastName = 'TEST Name 1',
            status = 'Open',
            Phone = '5165039576',
            Email = '1@1.com',
            Classification__c = 'Consumer',
            RecordTypeId = lead.Id,
            Equifax_Household_ID__c = '123'
        ); 
           Test.startTest();
            List<Account> results;
        
            System.runAs(u) {
                insert testLead1;
                insert testAccount1;
            HouseholdpageController ctrl = new HouseholdpageController(new ApexPages.StandardController(testLead1));
            results = ctrl.getAccounts();
            }
        Test.stopTest();
    }
}

Thanks,
Jason Liu
Best Answer chosen by Jason Liu 7
Amit Chaudhary 8Amit Chaudhary 8
Please check below blog for test classes. I hope that will help you
1) http://amitsalesforce.blogspot.in/search/label/Test%20Class
2) http://amitsalesforce.blogspot.in/2015/06/best-practice-for-test-classes-sample.html

Pleae try below code. I hope that will help you
@isTest
private class HouseholdpageControllerTest 
{
    static testMethod void UnitTest() 
	{
        
        Account testAccount1 = new Account(       
          FirstName='Test Description', 
          LastName='Test Last Name',
          RecordTypeId = rt.Id,
		  Equifax_Household_ID__c = '123',
          Loan_Balance__c = 321,
          Deposit_Balance__c  = 456
        );
		insert testAccount1;
		
        Lead testLead1 = new Lead(
            LastName = 'TEST Name 1',
            status = 'Open',
            Phone = '5165039576',
            Email = '1@1.com',
            Classification__c = 'Consumer',
            RecordTypeId = lead.Id,
            Equifax_Household_ID__c = '123'
        ); 
		insert testLead1;
		
		Test.startTest();
		
			ApexPages.StandardController sc = new ApexPages.StandardController(testLead1);
			myControllerExtension testAccPlan = new myControllerExtension(sc);

			PageReference pageRef = Page.AccountPlan; // Add your VF page Name here
			pageRef.getParameters().put('id', String.valueOf(testLead1.Id));
			Test.setCurrentPage(pageRef);
			try
			{
				List<Account> lstAcc = testAccPlan.getAccounts();
			}catch(Exception ee)
			{}
		Test.stopTest();
    }
}

Please follow below salesforce Best Practice for Test Classes :-

1. Test class must start with @isTest annotation if class class version is more than 25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the  percentage of code coverage ,we should make sure that every use case should covered including positive, negative,bulk and single record .
Single Action -To verify that the the single record produces the correct an expected result .
Bulk action -Any apex record trigger ,class or extension must be invoked for 1-200 records .
Positive behavior : Test every expected behavior occurs through every expected permutation , i,e user filled out every correctly data and not go past the limit .
Negative Testcase :-Not to add future date , Not to specify negative amount.
Restricted User :-Test whether a user with restricted access used in your code .10. Test class should be annotated with @isTest .
11 . @isTest annotation with test method  is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access specifier .
14. classes with @isTest annotation can't be a interface or enum .
15. Test method code can't be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out mock .
19. You can't  send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
23. Create TestFactory class with @isTest annotation to exclude from organization code size limit .
24. @testSetup to create test records once in a method  and use in every test method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is  not grater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the process .


Please let us know if this post will help you

 

All Answers

pconpcon
So the problem is that you are using the ger parameters instead of using the standard controller method to get the record id.  Because you are doing this, you are not getting anything back.  You should just remove the currentlead assignment in your getAccounts.  Also, since you do not have any asserts in your test, how do you know they are not working?

NOTE: When including code please use the "Add a code sample" button (icon <>) to increase readability and make referencing code easier.
Amit Chaudhary 8Amit Chaudhary 8
Please check below blog for test classes. I hope that will help you
1) http://amitsalesforce.blogspot.in/search/label/Test%20Class
2) http://amitsalesforce.blogspot.in/2015/06/best-practice-for-test-classes-sample.html

Pleae try below code. I hope that will help you
@isTest
private class HouseholdpageControllerTest 
{
    static testMethod void UnitTest() 
	{
        
        Account testAccount1 = new Account(       
          FirstName='Test Description', 
          LastName='Test Last Name',
          RecordTypeId = rt.Id,
		  Equifax_Household_ID__c = '123',
          Loan_Balance__c = 321,
          Deposit_Balance__c  = 456
        );
		insert testAccount1;
		
        Lead testLead1 = new Lead(
            LastName = 'TEST Name 1',
            status = 'Open',
            Phone = '5165039576',
            Email = '1@1.com',
            Classification__c = 'Consumer',
            RecordTypeId = lead.Id,
            Equifax_Household_ID__c = '123'
        ); 
		insert testLead1;
		
		Test.startTest();
		
			ApexPages.StandardController sc = new ApexPages.StandardController(testLead1);
			myControllerExtension testAccPlan = new myControllerExtension(sc);

			PageReference pageRef = Page.AccountPlan; // Add your VF page Name here
			pageRef.getParameters().put('id', String.valueOf(testLead1.Id));
			Test.setCurrentPage(pageRef);
			try
			{
				List<Account> lstAcc = testAccPlan.getAccounts();
			}catch(Exception ee)
			{}
		Test.stopTest();
    }
}

Please follow below salesforce Best Practice for Test Classes :-

1. Test class must start with @isTest annotation if class class version is more than 25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the  percentage of code coverage ,we should make sure that every use case should covered including positive, negative,bulk and single record .
Single Action -To verify that the the single record produces the correct an expected result .
Bulk action -Any apex record trigger ,class or extension must be invoked for 1-200 records .
Positive behavior : Test every expected behavior occurs through every expected permutation , i,e user filled out every correctly data and not go past the limit .
Negative Testcase :-Not to add future date , Not to specify negative amount.
Restricted User :-Test whether a user with restricted access used in your code .10. Test class should be annotated with @isTest .
11 . @isTest annotation with test method  is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access specifier .
14. classes with @isTest annotation can't be a interface or enum .
15. Test method code can't be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out mock .
19. You can't  send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
23. Create TestFactory class with @isTest annotation to exclude from organization code size limit .
24. @testSetup to create test records once in a method  and use in every test method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is  not grater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the process .


Please let us know if this post will help you

 
This was selected as the best answer
Austin GAustin G
To piggyback off Amit's answer, point 20 may be the issue. In your @isTest annotation, try using:
@isTest(SeeAllData = true)
private class HouseholdpageControllerTest
/* rest of the test class goes here */

You also may want to try running the queries in your code manually, either in an anonymous window or in the SOQL explorer in the dev console. If you can run the queries and return data in an anonmyous execution or the SOQL explorer, but not from your test class, there's a good chance that all you need to do is set the SeeAllData flag in your annotation.
pconpcon
Please Please Please Please Please do NOT use seeAllData! There is practically no reason to ever use this in your tests. You should create all of your test data inside your test. If you do not know exactly why are using seeAllData then you should not be using it.
Austin GAustin G
@pcon that is a good point, I'll leave my answer up there as an example of what not to do and how lazy tests get written. Reality checks are a good thing.

For the original question, this bit from the doc may help:
"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."
Your trigger is querying data from Leads, it may be an access issue trying to query that data inside a text context. Maybe try having your test create specific leads for the account as well and see if that helps.
 
pavan kumar 1156pavan kumar 1156
Hi @Amit Chaudhary 8 , Have  a small doubt  in the code below we are passing the valuse as bcz of it is unit test can i know what is reson that we are passing record typre id?
User-added image