+ Start a Discussion
Sakthi169Sakthi169 

How to write the test class for before insert and before update

Hi to all,

I am new to salesforce,i dont know how to write apex class for trigger.when i click the deploy i will get the following error.
Your organization's code coverage is 2%. You need at least 75% coverage to complete this deployment. Also, the following triggers have 0% code coverage. Each trigger must have at least 1% code coverage.
This is my trigger
trigger LeadAssignmentTrigger on Broker__c (before insert,before update) 
    {
       List<Broker__c > leadsToUpdate = new List<Broker__c >();
        for (Broker__c broker: Trigger.new)
        {     
            if (broker.Referral_ID__c!= NULL)
            {
                String str = broker.Referral_ID__c;
                Integer ln = str.Length();
                String likeStr = '%'+str.subString(ln-10, ln-7)+'%'+str.subString(ln-7, ln-4) +'%'+ str.subString(ln-4);

                // Find the sales rep for the current zip code
                List<User> zip = [select Id from User
                                       where MobilePhone Like : likeStr];

                // if you found one
                if (zip.size() > 0) 
                {    
                    //assign the lead owner to the zip code owner
                    broker.OwnerId = zip[0].Id; 
                    leadsToUpdate.add(broker);
                }
               else
                {
                    // Throw Error
                    broker.addError('Invalid Referrel ID');
                }
            } 
        }
     }
I am new to salesforce.Anyone help me to how to write apex class(test class) for above trigger.
 
Prem Anandh 1Prem Anandh 1
Hi Uma, 

Test class is notthing you have create a record for testing and the created record should check with all the criteria. i.e How we are testing through UI same we have to create a record/update using DML operation. 

Please see below example. 
 
@isTest 
private class HelloWorldTestClass {
    static testMethod void validateHelloWorld() {
      
       Book__c b = new Book__c(Name='Behind the Cloud', Price__c=100);
       System.debug('Price before inserting new book: ' + b.Price__c);

       // Insert book
       insert b;
    
       // Retrieve the new book
       b = [SELECT Price__c FROM Book__c WHERE Id =:b.Id];
       System.debug('Price after trigger fired: ' + b.Price__c);

       // Test that the trigger correctly updated the price
       System.assertEquals(90, b.Price__c);
    }
}

FYI, I noticed SOQL is written inside for loop. It should not be a case else it will hit 101 SOQL governer limits when you are doing bulk insertion/updations.

Thanks,
Prem Anandh
 
Shashikant SharmaShashikant Sharma
Hi,

Tr this:
 
@isTest
private class LeadAssignmentTriggerTest{

    private static TestMethod void testTrigger(){
        
        //Step 1 : Data Insertion
        //Insert all the data required for your trigger according to your logic written in the trigger
        
        //Try to give unique values in fields while creating test data, like Name = 'TestAccountName' etc
        
        //If any configuration setting is also needed in your trigger insert that as well
        //If you create any configuration setting then you will need to create a user also so that mixed dml exception do not occur
        User userObj =  new User( Id = UserInfo.getUserId() );
        userObj.MobilePhone = '5555555555';
        update userObj;
        
        test.startTest();
        
        Broker__c broker = new Broker__c( Referral_ID__c = '5555555555');
        insert broker;
        
        test.stopTest();
        // IF you have used any static variables
        
        
    }


}

You can read more about test class development here: http://forceschool.blogspot.in/2011/06/testing-trigger-structure.html

Thanks
Shashikant
Amit Chaudhary 8Amit Chaudhary 8
Just update your Trigger as you are using SOQL inside for loop
@isTest 
private class LeadAssignmentTriggerTest 
{
    static testMethod void validateHelloWorld() 
	{
		Broker__c broker =  new Broker__c();
		//broker.Referral_ID__c = add valid value here
		// Add all required field here
		
		try
		{
			insert broker;
		}
		Catch(Exception ee)
		{
		}
		
    }
}

Please check below post for test classes.
1) http://amitsalesforce.blogspot.in/search/label/Test%20Class
2) http://amitsalesforce.blogspot.in/2015/06/best-practice-for-test-classes-sample.html


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
Sakthi169Sakthi169
Hi shashikant,

I got the follwing error when i run the test class

System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is Mandatory: []
Prem Anandh 1Prem Anandh 1

Add City while inserting the record. 

Ex. obj.City = 'Test'; 

Sakthi169Sakthi169
Hi Prem,

I got following error

Error: Compile Error: Variable does not exist: Obj.City 
Prem Anandh 1Prem Anandh 1
Please place the exact API Name. I am not sure about your API name. Check in your object 
Amit Chaudhary 8Amit Chaudhary 8
Please try below code.
@isTest 
private class LeadAssignmentTriggerTest 
{
    static testMethod void validateHelloWorld() 
	{


        User userObj =  new User( Id = UserInfo.getUserId() );
        userObj.MobilePhone = '5555555555';
        update userObj
		
		
		test.startTest();		
			try
			{
				Broker__c broker =  new Broker__c();
				broker.Referral_ID__c = '55555555';
				broker.City ='New York';
				// Add all required field here
				insert broker;
			}
			Catch(Exception ee)
			{
			}
		test.stopTest();	
    }
}

 
Sakthi169Sakthi169
Hi amit,

@isTest 
private class LeadAssignmentTriggerTest 
{
    static testMethod void validateHelloWorld() 
    {
        Broker__c broker =  new Broker__c();
        //broker.Referral_ID__c = add valid value here
        // Add all required field here
        broker.Referral_ID__c='5555555555';
        broker.City__c='Mumbai';
        
        try
        {
            insert broker;
        }
        Catch(Exception ee)
        {
        }
        
    }
}


i got the following errror

AccountBrowseExtensionTesttestAccountBrowseSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: [] 
Stack Trace: Class.AccountBrowseExtensionTest.testAccountBrowse: line 20, column 1
CloseActivityControllerTesttestCloseActivitySystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: [] 
Stack Trace: Class.CloseActivityControllerTest.testCloseActivity: line 13, column 1
changeOwnerControllerTesttestchangeOwnerSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: [] 
Stack Trace: Class.changeOwnerControllerTest.testchangeOwner: line 20, column 1
cntactsclassTesttestcntactsSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: [] 
Stack Trace: Class.cntactsclassTest.testcntacts: line 13, column 1
LogACallControllerTesttestLogACallSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: [] 
Stack Trace: Class.LogACallControllerTest.testLogACall: line 14, column 1
RedirectControllerTesttestRedirectSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: [] 
Stack Trace: Class.RedirectControllerTest.testRedirect: line 20, column 1
TestAccountSharetestSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mobile Number is mandatory after Appointment is fixed.: [] 
Stack Trace: Class.TestAccountShare.test: line 40, column 1
 
Prem Anandh 1Prem Anandh 1
Look like you have to mention mandatory fields while creating record. Please see above examples and pass your code here
Sakthi169Sakthi169
Hi amit,

When run the apex class in sandbox it working fine with trigger,but move into production it shows the above error again.
 
Mahesh DMahesh D
Hi Uma,

Temporary solution is:

Remove the Mandatory check on City and Mobile Number and aslo de-activate the Validation on it.
But this is only for temporary purpose. Once you are done with this deployment.

You have to modify all your existing TestClasses whereever it is showing error and make sure that you are provding all mandatory values.

Note: Its only Temporary solution only for this deployment if you dont have much time to fix all Test Classes.

Please do let me know if it helps you.


Regards,
Mahesh
Amit Chaudhary 8Amit Chaudhary 8
Hi Umadevi S,

It look like some one created the validation directly in production which is not available in sandbox. You need to fix all below Test classess in Sandbox and need to add City value same like above test class.
  1. AccountBrowseExtensionTest
  2. CloseActivityControllerTest
  3. changeOwnerControllerTest
  4. cntactsclassTest
  5. LogACallControllerTest
  6. RedirectControllerTest
  7. TestAccountShare
I will never commend you to deactivate the validation rule.

You can also install the below app exchange product to see the code coverage of each class.
Code Coverage Report ( Now you can view the overall and individual entity code coverage in your organization. The results of the code coverage can be downloaded in Excel format )
https://appexchange.salesforce.com/listingDetail?listingId=a0N3000000DXzlpEAD

Let us know if this will help you


 
Sakthi169Sakthi169
Hi,

I add the city in all test class and it shows the same error.
Prem Anandh 1Prem Anandh 1
Are you facing error while deploying or sandbox itself?
Sakthi169Sakthi169
Hi Prem,

While deploying only
Prem Anandh 1Prem Anandh 1
For now you can deactivate the Validation rule in production and deploy else try full fill the validation criteria in Test Classes. 
Mahesh DMahesh D
Hi Uma,

After you add the City in all the below classes
  1. AccountBrowseExtensionTest
  2. CloseActivityControllerTest
  3. changeOwnerControllerTest
  4. cntactsclassTest
  5. LogACallControllerTest
  6. RedirectControllerTest
  7. TestAccountShare
You have to include them as part of outbound change set / package.xml to deploy into production. Means you need to include them as part of your deployment.

Hi Amit,

Code Coverage Report application needs Run All Test and generally in production, it is not suggestable to do 'Run All Test' all the time.
And also here the issue is with the Validation Rule but not the Code Coverage issue. Hence we can concentrate on either fixing all of them if there is no time crunch and pushing them into Production orelse temporarily have to de-activate and fix the errors at a later stage. Yes no one will suggest this as a permanent solution but based on time and situaltion have to follow.

Regards,
Mahesh
Amit Chaudhary 8Amit Chaudhary 8
Hi Mahesh,

Yes That will better if we can do run all test in production because test classes are failing production only not in sandbox ? So that will better we can execute the run- All Test in production to see which all test classes are failing.

After that we should fix the all test classes in sandbox and need to deploy all failed test classes again in production. Deactivate the validation rule is not a solution.

If you see the initial question due to test classes failure code coverage issue is coming also

"Your organization's code coverage is 2%. You need at least 75% coverage to complete this deployment. Also, the following triggers have 0% code coverage. Each trigger must have at least 1% code coverage "

Can you please let me know what is wrong is we will execute the Run-All Test ??
 
Sakthi169Sakthi169
Hi Mahesh,

If i add all test class or wat??? Now i select only one class
 
Mahesh DMahesh D
Hi Amit,

As part of Deployment it will automatically run all the Test Classes and show all the errors, we don't need to do Run All Test separately.

If you do Run All Test separately there are 2 things which we need to consider:

(1) Based on number of Test Classes it may take hours also, as we have 800+ test classes it is taking more than 2 hours to do Run All Test.
(2) Auto Sequence number will be utilized as part of Run All Test, hence the Case numbers will be moved to a new number without having real cases.

Hence I won't recommend to do Run All Test in Production. Also Deployment is also doing the samething in the background.

De-activating the Validation is not the permanent solution but if she is crunch of time then it will be suggestable and fix them later otherwise have to  fix all issue no itself.

Hope I answered your questions.

Regards,
Mahesh 
Sakthi169Sakthi169
What is the Package.Xml???
Mahesh DMahesh D
Hi Uma,

Can you show me your ourbound change set, take a printscreen and paste it here.

You have to add all your modified Test Classes into outbound changeset and deploy them. Hope you created a new Outbound Changeset.

Regards,
Mahesh
Amit Chaudhary 8Amit Chaudhary 8
Hi Umadevi S,

Please add city in all below test class and deploy all below test class in production together in production (with change set).
  1. AccountBrowseExtensionTest
  2. CloseActivityControllerTest
  3. changeOwnerControllerTest
  4. cntactsclassTest
  5. LogACallControllerTest
  6. RedirectControllerTest
  7. TestAccountShare


 
Mahesh DMahesh D
Hi Uma,

We can do deployment in multiple ways:

(1) Using Eclipse -- Deploy to server option we will use it to deploy.
(2) Using Changeset -- We will use outbound change set.
(3) Using ANT based migration tool. -- If you use ANT based migration tool then we have to use package.xml.

Regards,
Mahesh
Sakthi169Sakthi169
Hi Mahesh,

i am Using Changeset -- We will use outbound change set.
Sakthi169Sakthi169
Hi Amit,

I added city but i got same errror
Mahesh DMahesh D
Hi Uma,

Can you paste the printscreen of your Outbound Changeset so that we will know what are all the classes you included and also paste the latest error.

You have to create a brand new Outbound change set with all the additional test classes.

Regards,
Mahesh
Amit Chaudhary 8Amit Chaudhary 8
Hi Umadevi,

Please include all above test classes also in your change set. Feel free to connect with me on skype chaudharyamit21

Hi Mahesh,

Please check below salesforce post. Which recomment to do Run-All test in production before deployment.
https://developer.salesforce.com/docs/atlas.en-us.dev_lifecycle.meta/dev_lifecycle/deploy.htm

User-added image

Please let me know if i am wrong ?
Mahesh DMahesh D
Hey Amit,

Its Staging its not Production.

it’s advisable to manually run all tests in your staging environment to avoid any possible issues before the production deployment.

No one will recommend to manually do Run All Test in production, because the deployment process is doing the same.

Regards,
Mahesh
Mahesh DMahesh D
Hi Uma,

If you have any questions further or if you want me to help you by connecting to your screen then connect me at mahesh.static@gmail.com

Regards,
Mahesh
Sakthi169Sakthi169
User-added imageUser-added image

Hi Mahesh,

I attached the error image file.
 
Sakthi169Sakthi169
Hi Amit,

I any another way to update owner(standard field) in custom page  without using trigger
Sakthi169Sakthi169
Hi Amit,

For the below condition i created the trigger.

I need to update owner(Standard Field) name on custom page(Buyer) using Referral Id(mobile of Lead owner)..
The Referral Id(Mobile No) already present in user details.
For example the buyer is created by me but i put the Referral Id was my manager mobile no.After created the Buyer i need to updated owner as my manager name not mine.If the Referral Id is not user table i need to throw the error and dont create. Now it show my name and the lead created.Without trigger i can achieve this??? If there is any another option is there???
Sakthi169Sakthi169
Hi Mahesh,

I don't want to interfering another test classes.If any other way is there to solve this???
Mahesh DMahesh D
Hi Uma,

Please connect me at mahesh.static@gmail.com

Regards,
Mahesh