Need help in improving test coverage to 75% - Apex Class - salesforce

I am not able to upload my package because test coverage is below 75%.
How to improve coverage. How to write test methods for triggers.
Please help.
I have tried this code :
This is my controller class:
public class MyController{
public List<Merchandise__c> merch{get;set;}
public Merchandise__c toDelete{get;set;}
public MyController(){
merch = [SELECT ID,Merchandise__c.name,Price__c,Description__c,Total_Inventory__c FROM Merchandise__c];
}
public pageReference del(){
string id = Apexpages.currentpage().getParameters().get('merchandiseId');
toDelete = [SELECT Id,Merchandise__c.name,Price__c,Description__c,Total_Inventory__c FROM Merchandise__c WHERE Id =: id];
delete toDelete;
return null;
}
public pageReference add(){
Merchandise__c item = new Merchandise__c(
Name = 'Enter Name',
Description__c = 'Enter Description',
Price__c = 0.00,
Total_Inventory__c = 0
);
merch.add(item);
insert item;
return null;
}
public PageReference save(){
string id = Apexpages.currentpage().getParameters().get('merchandiseId');
Merchandise__c toUpdate = [SELECT Name, Description__c, Price__c FROM Merchandise__c WHERE ID =: id];
update toUpdate;
return null;
}
}
I have craeted this Test Class :
#isTest
Public Class demoTest{
static testMethod void checkDatatableData() {
List<Merchandise__c> merch;
Test.startTest();
merch = [SELECT ID,Merchandise__c.name,Price__c,Description__c,Total_Inventory__c FROM Merchandise__c];
Test.stopTest();
}
static testMethod void checkAdd() {
Merchandise__c item = new Merchandise__c(
Name = 'Enter Name',
Description__c = 'Enter Description',
Price__c = 0.00,
Total_Inventory__c = 0
);
Test.startTest();
insert item;
System.assertNotEquals(null,item.Id);
List<Merchandise__c> merchItem = [SELECT Id FROM Merchandise__c WHERE Id =: item.Id];
System.assertEquals(1,merchItem.size());
Test.stopTest();
}
static testMethod void checkUpdateDelete() {
Merchandise__c testmerch = new Merchandise__c(
Name = 'NewProduct',
Description__c = 'this is anew product',
Price__c = 20.00,
Total_Inventory__c = 100
);
Test.startTest();
insert testmerch;
system.assertNotEquals(null,testmerch.Id);
testmerch.Price__c = 40.00;
update testmerch;
Merchandise__c updatedmerch = [SELECT Id,Price__c FROM Merchandise__c WHERE Id =: testmerch.Id];
system.assertEquals(40.00,updatedmerch.Price__c);
Merchandise__c toDelete = [SELECT ID FROM Merchandise__c WHERE Id =: testmerch.Id];
system.assertNotEquals(null,toDelete.Id);
delete toDelete;
Test.stopTest();
}
}
Can you please tell me what changes I need to do to improve coverage?

This link should tell you what you need to know.
http://wiki.developerforce.com/page/An_Introduction_to_Apex_Code_Test_Methods
Basically you need to replicate the functionality of the trigger in your test methods, so for instance if you have an after update trigger case that runs when it moves from Open to Closed you first need to create a test method for your trigger then within the test method insert a case record for testing, which may also require a contact or an account etc, then you change the value of the case to closed and then run an update method. This is very simplistic but that is the idea. So when writing test classes try to think about what your triggers and classes do and then try to automate what the user would do in your test methods, making sure to cover all your bases including where the piece of apex should fire an exception.
Try to avoid using hard-coded Id's wherever possible.
These links may also help
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_best_practices.htm
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_qs_test.htm

Related

Getting dupicate agent names

Here am using map ,not abled to understand how to solve the duplicate name,i want one agent name against number of payments(child of opp)
how do I get unique names of users
public class First_Pay_ClearRates_Controller {
#AuraEnabled
public static Map<Id,User> fetchUsers() {
// List<User> userList= [SELECT Id, Name FROM User WHERE Profile.Name = 'Sales' LIMIT 20];
Map<Id,User> userMap= new Map<Id,User>([SELECT Id, Name FROM User WHERE Profile.Name = 'Sales' LIMIT 20]);
return userMap;
}
#AuraEnabled
public static List<Opportunity> getOpps(Map<Id,User> usrMap){
Map<Id,List<Opportunity>> oppMap = new Map<Id,List<Opportunity>>();
List<Opportunity> oppList = new List<Opportunity>();
List<Payments__c> payList= new List<Payments__c>();
List<Payments__c> payList1= new List<Payments__c>();
// prev key Agent_Name_User__c
// AND First_Payment_Date__c=THIS_MONTH
for(Opportunity o: [SELECT Id,First_Payment_Date__c,OwnerId,Owner.Name ,of_Payments_Made__c,PaymentsCounter__c,CollectedPaymentCount__c,First_Client_Payment_Collected_Date__c From Opportunity WHERE OwnerId IN: usrMap.keyset() AND First_Payment_Date__c!=null LIMIT 20]){
if(!oppMap.containsKey(o.OwnerId)){
oppMap.put(o.OwnerId,new List<Opportunity>());
}
o.PaymentsCounter__c=0;
o.CollectedPaymentCount__c=0;
//AND Due_Date__c=THIS_MONTH
for(Payments__c p :[Select Id,Opportunity__c,Payment_Collected__c,Due_Date__c FROM Payments__c WHERE Opportunity__c =: o.Id ]){
if(!p.Payment_Collected__c){
payList.add(p);
o.PaymentsCounter__c= payList.size();
}else if(p.Payment_Collected__c){
payList1.add(p);
o.CollectedPaymentCount__c= payList1.size();
}
}
oppList.add(o);
oppMap.put(o.OwnerId,oppList);
}
return oppList;
}

Splitting row into several nested objects

I've got the following query:
select id, name, email, supervisor, createdBy, createdAt, changedBy, changedAt from XXX
Now, I'd like to map each row into something that looks like this:
public class Organisation{
public int Id{get; set; }
public string Name{get; set; }
public ContactInfo Contact{get;set;}
public Action CreatedBy{get;set;}
public Action ChangedBy{get;set;}
}
public class ContactInfo{
public string Name{get;set;}
public string Email{get;set;}
}
public class Action{
public string Username{get;set;}
public DateTime At{get;set;}
}
I've seen some examples that show how to partition the info, but it seems like will not work in this example. Can it be done or should I map my query into a helper object which will then be mapped into these classes?
Thanks.
Luis
Dapper allows you to map a single row to multiple objects. This is a
key feature if you want to avoid extraneous querying and eager load
associations.
You can read about it more here
Below is an example:
[Test]
public void Test_Multi()
{
using (var conn = new SqlConnection(#"Data Source=.\sqlexpress;Integrated Security=true; Initial Catalog=foo"))
{
var result = conn.Query<Organisation, ContactInfo, Action, Action, Organisation>(
#"select Id = 100, Name = 'Foo',
Name = 'Contact Name', Email = 'contact#foo.com',
Username = 'The Creator', At = '12/25/2017',
Username = 'The Modifier', At = '12/26/2017' ",
(org, contact, cretedBy, changedBy) =>
{
org.Contact = contact;
org.CreatedBy = cretedBy;
org.ChangedBy = changedBy;
return org;
}, splitOn: "Id, Name, Username, Username").First();
Assert.That(result.Id, Is.EqualTo(100));
Assert.That(result.Contact.Email, Is.EqualTo("contact#foo.com"));
Assert.That(result.CreatedBy.Username, Is.EqualTo("The Creator"));
Assert.That(result.ChangedBy.Username, Is.EqualTo("The Modifier"));
}
}

how to fix System.NullPointerException: Attempt to de-reference a null object in apex class using Map<parentId, child>?

Getting the error in line " taskObj.OwnerId = ConMap.get(ben.contact__c).contact__r.OwnerId;" becasue the ownerid field is on contact.
Contact is the parent of benefit, Here I am getting all the benefits in start method. I want to add contactid only once if it has more than one child for that I used SET. I want to use maps as I need to get the contact OwnerId field from contact object which I am fetching in the query in start method. How do I Access contact.ownerId field using a map? below is the code.
global Database.QueryLocator start(Database.BatchableContext bc) {
Query='select contact__r.ownerId, contact__c, Task_creation_date__c, Status__c, task_created__c, type__c from Benefit__c Where Task_creation_date__c= TODAY AND Status__c IN (\'Active\',\'Pending\') AND Task_created__c =FALSE AND Type__c!=\'Short Term Medical\'';
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext bc, List<Benefit__c> scope){
// process each batch of records
List<Contact> contacts = new List<Contact>();
List<Task> TaskList = new List<Task>();
set<id> conset = New set<id>();
Map<id,benefit__c> ConMap = new map<id,Benefit__c>();
for (Benefit__c b : scope) {
conset.add(b.contact__c);
ConMap.put(b.contact__c, b);
b.task_created__c = TRUE;
}
system.debug('contact and its benefit------'+ConMap);
recordsProcessed = conset.size();
//List<Contact> tempList = new List<Contact>();
// tempList = [Select Id,OwnerId, firstname from Contact where Id IN:(conset)];
if(!ConMap.isEmpty())
{
for(Benefit__c ben : ConMap.values())
{
Task taskObj = new Task();
taskObj.OwnerId = ConMap.get(ben.contact__c).contact__r.OwnerId;
I want to populate contact ownerid as the task ownerid but how do I access it from the map and keep the unique contact id in the map?
I see that the batch query does not have the filtering condition 'Contact__c != null'. So, it's possible that one of the benefit records is missing value in the 'Contact__c' field and you wouldn't find it in the map. You can solve this in two ways:
Add 'Contact__c != null' to the selector query if you don't care about those records.
(Or)
Check for 'null' value in the for loop as below:
if(!ConMap.isEmpty())
{
for(Benefit__c ben : ConMap.values())
{
if(String.isBlank(ben.Contact__c)){
/* continue;
or
throw exception()
*/
}
Task taskObj = new Task();
taskObj.OwnerId = ConMap.get(ben.contact__c).contact__r.OwnerId;
I re wrote the code to resolve this nd optimize the code as below.
public with sharing class MyBatch implements Database.Batchable<AggregateResult>{
public Iterable<AggregateResult> start(Database.BatchableContext context)
{
return [
SELECT Contact__c, Contact__r.OwnerId owner FROM Benefit__c
WHERE Contact__c != null AND ...
GROUP BY Contact__c, Contact__r.OwnerId
];
}
public void execute(Database.BatchableContext context, List<AggregateResult> scope)
{
Set<Id> contactIds = new Set<Id>();
List<Task> tasks = new List<Task>();
for (AggregateResult aggregate : scope)
{
Id ownerId = (Id)aggregate.get('owner');
Id contactId = (Id)aggregate.get('Contact__c');
contactIds.add(contactId);
tasks.add(new Task(OwnerId=ownerId, /*other fields*/));
}
insert tasks;
List<Benefit__c> benefits = [
SELECT Id FROM Benefit__c WHERE Contact__c IN :contactIds
];
for (Benefit__c benefit : benefits)
benefit.Task_Created__c = true;
update benefits;
}
public void finish(Database.BatchableContext context) { /*additional logic*/ }}

need help on how to achieve 100% in the test class

I have been trying to write test class for 100% coverage. I have difficulty in understanding how to call the standard controller and call the parameterised constructor also set the page to the current page as the current page.
On the account view page, I have overridden the new button on the related list of a custom object. I am able the use the same class when I edit the record. On both the edit record view page and the new record view page I am able to retrieve the account id. Currently I am able achieve 65% coverage. I am not sure what am I doing wrong. Please help if possible. I have attached the code below.
Thanks
Gayatri
//my Class
public class NewTaxExempt{
public TaxExempt__c obj {get; set;}
public String selectedIso {get;set;}
public List<selectOption> isoCodes {
get {
List<selectOption> options = new List<selectOption>();
for (State__c iso : State__c.getAll().values())
options.add(new SelectOption(iso.State_ISO__c,iso.State_Name__c+' - '+iso.State_ISO__c));
return options;
}
set;
}
// onload standard controller will be called.
public NewTaxExempt(ApexPages.StandardController controller) {
ID idte=controller.getRecord().id;
if(idte==null){
obj=(TaxExempt__c)controller.getRecord();
}
else{
obj= [Select Account__c, Certificate_ID__c, Certificate_Type__c,Description__c, Issuing_Jurisdiction__c,Status__c,Tax_Exempt_Effective_Date__c,Tax_Exempt_Expiration_Date__c from TaxExempt__c where id=:idte];
}
}
//on click on cancel button
public PageReference cancel() {
return new PageReference('/'+obj.account__c);
}
//on click on Save button
public PageReference save() {
obj.Issuing_Jurisdiction__c=selectedIso;
if(obj.id==null){
insert obj;
}
else{
update obj;
}
return new PageReference('/'+obj.account__c);
}
}
//my test class
#isTest
public class NewTaxExemptTest{
public static testMethod void whenIssueJurisdictionIsBlankDefaultValueIsSet(){
try{
BET_ObjectFactory.generateTaxExemptRequirements();
Account aobj = ( Account)TestFactory.createSObject(new Account(Name='test acc gs250144'),true);
PageReference ref = Page.NewTaxExempt;
Test.setCurrentPage(ref);
TaxExempt__c obj=new TaxExempt__c();
obj.account__c=aobj.Id;
obj.Issuing_Jurisdiction__c='RI';
ApexPages.StandardController sc = new ApexPages.StandardController(obj);
NewTaxExempt ob=new NewTaxExempt(sc);
ob.selectedIso='RI';
ob.obj=obj;
ob.save();
System.assertEquals(obj.Issuing_Jurisdiction__c,null);
List<State__c> stList=new List<State__c>();
State__c st=new State__c();
st.Name='ST_11009';
st.State_Name__c='Alabama';
st.State_ISO__c='AL';
st.State_Country_Name__c='United States';
st.State_Country_ISO__c='US';
stList.add(st);
State__c st1=new State__c();
st1.Name='ST_11008';
st1.State_Name__c='Alabama';
st1.State_ISO__c='AL';
st1.State_Country_Name__c='United States';
st1.State_Country_ISO__c='US';
stList.add(st1);
State__c st2=new State__c();
st2.Name='ST_11019';
st2.State_Name__c='Alaska';
st2.State_ISO__c='AK';
st2.State_Country_Name__c='United States';
st2.State_Country_ISO__c='US';
stList.add(st2);
State__c st3=new State__c();
st3.Name='ST_12009';
st3.State_Name__c='Arizona';
st3.State_ISO__c='AZ';
st3.State_Country_Name__c='United States';
st3.State_Country_ISO__c='US';
stList.add(st3);
State__c st4=new State__c();
st4.Name='ST_11309';
st4.State_Name__c='Arkansas';
st4.State_ISO__c='AR';
st4.State_Country_Name__c='United States';
st4.State_Country_ISO__c='US';
stList.add(st4);
State__c st5=new State__c();
st5.Name='ST_21009';
st5.State_Name__c='California';
st5.State_ISO__c='CA';
st5.State_Country_Name__c='United States';
st5.State_Country_ISO__c='US';
stList.add(st5);
State__c st6=new State__c();
st6.Name='ST_23';
st6.State_Name__c='California';
st6.State_ISO__c='';
st6.State_Country_Name__c='';
st6.State_Country_ISO__c='';
stList.add(st6);
insert stList;
List<State__c> allStates = [select State_Name__c, State_ISO__c, State_Country_Name__c, State_Country_ISO__c
from State__c
order by State_Name__c];
for(State__c stt : allStates){
if(stt.State_ISO__c == '' || stt.State_ISO__c == null){
ob.isoCodes.add(new SelectOption(stt.State_ISO__c, stt.State_Name__c));
}
else{
ob.isoCodes.add(new SelectOption(stt.State_ISO__c, stt.State_Name__c));
}
}
System.assertNotEquals(ob.isoCodes.size(),0);
}catch(Exception e){
System.debug('Gayatri exception :'+e);
}
}
public static testMethod void whenUserClicksCancel(){
BET_ObjectFactory.generateTaxExemptRequirements();
Account aobj = ( Account)TestFactory.createSObject(new Account(Name='test acc gs250144'),true);
// PageReference ref = new PageReference(pageName)
// ref.getParameters().put('TaxExempt__c',obj.Id);
// Test.setCurrentPage(ref);
PageReference ref = Page.NewTaxExempt;
Test.setCurrentPage(ref);
TaxExempt__c obj=new TaxExempt__c();
ApexPages.StandardController sc = new ApexPages.StandardController(obj);
NewTaxExempt ob=new NewTaxExempt(sc);
ob.cancel();
}
}
it's gonna be much easier if you knew what part of your code is missing in test coverage.
Go to developer console and run your test
on the bottom of the page select test tab
find your test from the right side (with title: Overall code coverage)
double click on your test
uncovered part will be in red. now try to write tests for them.
If you want to cover your class properties all you have to do is this:
#isTest static void myPropertiesTest(){
MyClass obj = new MyClass();
obj.myProperty = SomeValue;
// now assert a function in you class that uses this property.
// an easy and dumb way is to just assert the property.
System.assertEquals(SomeValue, obj.myProperty);
}

Salesforce Controller Extension Testing: System.QueryException: List has no rows for assignment to SObject

I'm looking for some help testing a controller extension. I keep receiving the error: "System.QueryException: List has no rows for assignment to SObject" which is referring to the SOQL statement in my class.
Class
public class productdata {
public productdata(ApexPages.StandardController controller) {
}
public String getTag(){
Product2 prod;
prod = [SELECT Name FROM Product2 WHERE Id = :ApexPages.currentPage().getParameters().get('id')];
return Prod.Name;
}
Test Class
#isTest
private class TestProductData {
static testMethod void TestProductDataMethod(){
Product2 TP = new Product2(Name='TestRecord');
insert TP;
System.assertEquals('TestRecord', TP.name);
PageReference pageRef = page.productpage;
Test.setCurrentPage(pageRef);
ApexPages.StandardController sc = new ApexPages.standardController(TP);
productdata controller = new productdata(new ApexPages.StandardController(TP));
ApexPages.currentPage().getParameters().put('id', '01t300000007hKrAAI');
controller.getTag();
}
Thanks!
You shouldn't manually assign your record ids (as they will change with each run of the test).
ApexPages.currentPage().getParameters().put('id', '01t300000007hKrAAI');
Instead do:
ApexPages.currentPage().getParameters().put('id', TP.id);

Resources