Salesforce Apex Test Class for an auto convert apex class. REceiving errors moving to production - salesforce

I have an apex class that works how I want it in the sandbox. Trying to move it to production and need to write a test class. Used an example provided but I continue to get errors when running test that the lead was already converted. Need Help!
#isTest
public class TestAutoConvertLeads{
static testMethod void createnewlead() {
User userToCreate = [Select id from user where profile.name='System Administrator' Limit 1];
Test.startTest();
Lead leadToCreate =new Lead();
List<id> Ids= New List<Id>();
leadToCreate.ownerid= userToCreate.id;
leadToCreate.LastName ='Gupta';
leadToCreate.LeadSource='Partner Referral';
leadToCreate.Rating='';
leadToCreate.Status='';
insert leadToCreate;
Ids.add(leadToCreate.id);
AutoConvertLeads.LeadAssign(Ids);
Test.stopTest();
}
}
Also adding original apex class:

Related

Salesforce deploy Apex Class to production 0% code coverage

I am using Salesforce and I want to deploy a custom Apex Class from my sandbox. In production there is no Apex Classes and the estimated code coverage is 0% so when I try to deploy my class I get the following error
Is there a way to deploy my class ?
The Class I want to deploy is here:
Public class AutoConvertLeads
{
#InvocableMethod
public static void LeadAssign(List<Id> LeadIds)
{
List<Database.LeadConvert> MassLeadconvert = new List<Database.LeadConvert>();
for(id currentlead: LeadIds){
Database.LeadConvert Leadconvert = new Database.LeadConvert();
Leadconvert.setLeadId(currentlead);
Leadconvert.setConvertedStatus('Qualified');
MassLeadconvert.add(Leadconvert);
}
if (!MassLeadconvert.isEmpty()) {
List<Database.LeadConvertResult> lcr = Database.convertLead(MassLeadconvert);
}
}
}
Test Class:
#isTest
Private class UnitTest_AutoConvert
{
Static TestMethod void AutoConvert()
{
// Create the Lead object
Lead testLead = new Lead(
FirstName='Demo 100800',
LastName = 'Demo 100800 UnitTest',
Status='Qualified',
company='Lacosta'
);
insert testLead;
test.StartTest();
List<Lead> lstOfLeadids = [ testLead.Id ]
AutoConvertLeads.LeadAssign(lstOfLeadIds)
test.stopTest();
}
}
In order to meet the production deployment requirements you must meet the testing requirements. At a basic level, this means that you must maintain 75% line coverage between your production code and your test classes. This is at the aggregate level - so you can have some Apex classes with more or less coverage, but it must be 75% of all of code. Additionally, all Apex triggers require at least 1 line of test coverage to pass testing.
Unfortunately, you have provided limited information in your question. It would be helpful if you could provide the code for your test class so we could determine why Salesforce is not executing your tests during deployment. My initial guess is that you have not decorated your test class correctly for Salesforce to know it is a test class.
If you want a friendly introduction to testing, try the testing Trailhead: https://trailhead.salesforce.com/en/content/learn/modules/apex_testing
Take a look at the documentation as Svatopluk recommended. Specifically make sure that following things are happening:
1) The test class is marked as "#isTest"
2) The test method within the class is marked as "#isTest" or "testMethod" in the declaration.
3) The test class actually instantiates and runs code within your target class.
4) Deploy the TargetClass and TestClass in the same change set - this is so Salesforce can actually execute the tests during deployment.
Here is an example block:
#isTest
public class TestTargetClass{
public static testMethod void TestExectuableMethod() {
Test.startTest();
TargetClass instance_tc = new TargetClass();
instance_tc.executable_method();
Test.stopTest();
System.assert(<some sort of test to confirm that your TargetClass operates correctly>);
}
}
EDIT BASED ON POSTED TEST CODE:
Your test code has a number of issues.
First, it doesn't compile so I am not sure how you were able to get a passed test.
Lets review the errors in the following block:
test.StartTest();
List<Lead> lstOfLeadids = [ testLead.Id ]
AutoConvertLeads.LeadAssign(lstOfLeadIds)
test.stopTest();
The second line lstOfLeadids is of Type List of Lead but you are trying to populated it with an Id rather than a Lead.
This needs to be a List of Id since AutoConvertLeads.LeadAssign takes a List of Ids as the parameter.
Your instantiation of the lstOfLeadids is also wrong.
You are missing two semicolons.
Please use the following code:
test.StartTest();
List<Id> lstOfLeadids = new List<Id>{ testLead.Id };
AutoConvertLeads.LeadAssign(lstOfLeadIds);
test.stopTest();
In your actual AutoConvertLeads class, you are setting the lead convesion status to "Qualified". This didn't work on my Sandbox, but maybe it will on yours. You should be querying for the MasterLabel on the LeadStatus object of an IsConverted record to get the correct value.
You need to write test class to your class to be able to move it to production.
You can find basic explanation here

Flow: Use new type for variable?

I have a simple new class X which holds some results of a callout to an external system.
In a flow I need a variable of type X. Is there any way to declare a variable of that new type in a flow?
My new class is:
public class FooCalloutResult {
public Boolean success;
public Map<Id, Boolean> results;
public List<String> messages;
public FooCalloutResult() {
success = false;
results = new Map<Id, Boolean>();
messages = new List<String>();
}
}
If you want to get some data in a flow from an apex class you need to have an Process Invocable method - this is done by adding the #InvocableMethod annotation.
Example:
global class lookUpAccountAnnotation {
#InvocableMethod
public static List<String> getAccountIds(List<String> names) {
List<Id> accountIds = new List<Id>();
List<Account> accounts = [SELECT Id FROM Account WHERE Name in :names];
for (Account account : accounts) {
accountIds.add(account.Id);
}
return accountIds;
}
}
With this annotation the class will appear in your list of available elements in the Flow and you need to put the Input and Output that will go into it.
Depending on what kind of operation you want to do you might need to use the Process.plugin interface instead. Please check this article to see which option supports what kind of data to decide on what you need - https://help.salesforce.com/articleView?id=vpm_designer_elements_apex.htm&type=5

Not able to insert AccountPartner through test class in salesforce

I was not able to insert mock data for AccountPartner through test class. I tried by inserting 2 accounts and one Partner object. Actually same code is working in case of running from Apex class or executing from developer console. Please see the below code and output and let me know solution..
#isTest
private class TestAccountPartner {
private static testmethod void unittest(){
test.startTest();
Account sourceAccount = new Account();
Account targetAccount = new Account();
sourceAccount.AccountNumber='Number1';
sourceAccount.Name='name1';
targetAccount.AccountNumber='Number2';
targetAccount.Name='name2';
insert sourceAccount;
insert targetAccount;
Partner p = new Partner(AccountFromId=sourceAccount.ID, AccountToId=targetAccount.ID);
insert p;
Account sa = [select ID from Account where Name='name1'];
Account ta = [select ID from Account where Name='name2'];
System.debug('Source Account is: '+sa);
System.debug('Target Account is: '+ta);
List<Partner> partners = [select AccountFromId from partner];
System.debug('Partner objects are: '+partners);
List<AccountPartner> accountPartners = [select AccountFromId from AccountPartner];
System.debug('account partners are: '+accountPartners);
test.stopTest();
}
}
Output is:
07:24:48:174 USER_DEBUG [26]|DEBUG|Source Account is: Account:{Id=00128000007YZk7AAG}
07:24:48:174 USER_DEBUG [27]|DEBUG|Target Account is: Account:{Id=00128000007YZk8AAG}
07:24:48:176 USER_DEBUG [30]|DEBUG|Partner objects are: (Partner:{AccountFromId=00128000007YZk7AAG, Id=00I28000000ZeBTEA0})
07:24:48:177 USER_DEBUG [33]|DEBUG|account partners are: ()
It's been a while but I think this is because account partner is one of the special Role type relationships. Have you tried accessing the Target account's AccountPartner collection and using the add() method to add the Source account.
This isn't identical to your situation, but the solution has a similar example that is adding partners:
https://salesforce.stackexchange.com/questions/3805/how-to-update-account-object-when-related-accountpartner-is-updated-inserted-del

is it possible to archive the report of TestNG?

How do I archive the results (report) of the tests in Selenium 2 (Webdriver) so as to be able to return to them? Each performance suite overwrites the previous report, as it can be prevented? I use a simple html report.
//FOR EXAMPLE YOU WANT TO TEST THIS CLASS AND WANT TO CREATE NEW OUTPUT FOLDER FOR EACH EXECUTION
public class TestClass {
#Test
public void testME(){
System.out.println("Success");
}
}
//Then create new class which will be the start point of your execution, and run it from here
public class MainClass {
//This code will be your start point of execution
#Test
public void testCode(){
Random randomNo = new Random();
TestListenerAdapter listener = new TestListenerAdapter();
TestNG testng = new TestNG();
//Here you are changing Output directory and archive it for further
//use, OUTPUT FOLDER WILL BE ADDED BY APPPENDING RANDOM NUMBER ON IT
testng.setOutputDirectory("test-output"+randomNo.nextInt());
//ADD ALL TEST CLASSES WHERE YOUR TESTNG CODE IS PRESENT WITH #Test
testng.setTestClasses(new Class[]{TestClass.class});
testng.addListener(listener);
testng.run();
}
}

Salesforce (SFDC) - public, static, global keywords - use one list for entire class?

I'm having a hard understanding using public, static, and global keywords with my variables and methods.
Below is a snippet of my code. What I'm trying to do is upon page load, in my constructor create a Set of accountIDs that the user has access to (8-33 this is working). This set will be used to filter queries used in later methods.
What I'm finding is that public pageReference runSearch() has access to 'terrAccSet', but the public static List getsearchAccounts does not have access to it.
If I change it to public static Set terrAccSet, I don't get data in either of the system.debugs - what can I do?
global with sharing class MyClass {
public static List<FRM_Metrics_gne__c> accountSearchGmap {get; set;}
public Set<Id> terrAccSet;
public List<String> terrIdList;
//Constructor
public MyClass() {
terrAccSet = new Set<Id>();
terrIdList = new List<String>();
Set<Id> grpIdSet = new Set<Id>();
Id uid = '00570000001R95e'; //member of TWO territories
//UserTerritory Utid = [SELECT TerritoryId FROM UserTerritory where UserId = :userInfo.getUserId()];
List<UserTerritory> Utid = [SELECT TerritoryId FROM UserTerritory where UserId =: uid ];
for(UserTerritory usrTerr: Utid){
terrIdList.add(usrTerr.TerritoryId);
}
List<Group> grp = [Select Id from Group where RelatedID IN :terrIdList];
for (Group eachgroupd : grp ){
grpIdset.add(eachgroupd.Id);
}
List<AccountShare> accountidList = [SELECT AccountId,UserOrGroupId FROM AccountShare where UserOrGroupId in :grpIdset];
//all accounst that the user has access according to territory hiearchy
for(AccountShare eachas:accountidList ){
terrAccSet.add(eachas.AccountId);
}
}
public PageReference runSearch() {
//Has Data
system.debug('**terrAccSet runSearch** '+terrAccSet);
}
public static List<Custom_Object__c> getsearchAccounts(String multiSearchString) {
//terrAccSet variable is missing
system.debug('**terrAccSet getSearchAccounts** '+terrAccSet);
//logic
return accountSearchGmap;
}
}
Below is a snippet of my code. What I'm trying to do is upon page load, in my constructor create a Set of accountIDs that the user has access to (8-33 this is working). This set will be used to filter queries used in later methods.
This set should be an instance property, not static.
Use static when you want to create a method that does not affect the state of a controller or class, eg. a text parser-text in text out.
You should make the class Global if you want to create a package and make your class available outside your package so that other Apex code can invoke it, or if your class will create webService or REST methods to be exposed.
Public should be used to expose properties to the VisualForce pages that will consume the properties. Otherwise, use Private methods and properties for controller side only processing.
public static List getsearchAccounts(String multiSearchString) {
//terrAccSet variable is missing
system.debug('terrAccSet getSearchAccounts '+terrAccSet);
//logic
return accountSearchGmap;
}
This method should not be static because it accesses an instance property (it reads state).
Simple rule of thumb, if it is a visualforce page + controller, you shouldn't need anything static to do your normal work of querying the database and returning data to the page.

Resources