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
Eric DelgadoEric Delgado 

Salesforce Apex unit testing error

I am trying to create a Salesforce unit test for a new trigger I created.
trigger SOSCreateCaseCustom on SOSSession (before insert) {
    List<Event> aplist = new List<Event>();
    List<SOSSession> sosSess = Trigger.new;
    for (SOSSession s : sosSess) {
        try {
            Case caseToAdd = new Case();
            caseToAdd.Subject = 'SOS Video Chat';
            if (s.ContactId != null) {
                caseToAdd.ContactId = s.ContactId;
            } else {
                List<Contact> contactInfo = [SELECT Id from Contact WHERE Email = :s.AppVersion];
                if (!contactInfo.isEmpty()) {
                    caseToAdd.ContactId = contactInfo[0].Id;
                    s.ContactId = contactInfo[0].Id;
                }
            }
            insert caseToAdd; s.CaseId = caseToAdd.Id;
        }catch(Exception e){}
    }
}
Here is my unit test:
@isTest
private class SOSCreateCaseCustomTest {
    static testMethod void validateSOSCreateCase() {
        String caseSubject = 'SOS Video Chat';

        // set up case to add 
        SOSSession s = new SOSSession();
        insert s;

        Case caseToAdd = new Case(Subject='SOS Video Chat');
        caseToAdd.ContactId = s.ContactId;
        insert caseToAdd;

        Case ca = [SELECT Subject, ContactId from Case where Subject =: caseSubject];
        // Test that escaltion trigger correctly escalate the question to a case
        System.assertEquals(s.ContactId, ca.ContactId);
    }
}
I keep getting this error:
System.QueryException: List has more than 1 row for assignment to SObject

I am new to Apex and I have no idea how to fix this. Can someone give me some idea how to fix this? Thanks!
Best Answer chosen by Eric Delgado
Mahesh DMahesh D
Once you create the Outbound chnage set, click on the Add button and select the Apex Class, then select the Test Class.

Regards,
Mahesh

All Answers

Mahesh DMahesh D
Try this:
 
@isTest
private class SOSCreateCaseCustomTest {
    static testMethod void validateSOSCreateCase() {
        String caseSubject = 'SOS Video Chat';

        // set up case to add 
        SOSSession s = new SOSSession();
        insert s;

        //Case caseToAdd = new Case(Subject='SOS Video Chat');
        //caseToAdd.ContactId = s.ContactId;
        //insert caseToAdd;

        Case ca = [SELECT Subject, ContactId from Case where Subject =: caseSubject];
        // Test that escaltion trigger correctly escalate the question to a case
        System.assertEquals(s.ContactId, ca.ContactId);
    }
}

Regards,
Mahesh
Mahesh DMahesh D
Also I modified your class to support bulk number of records and to follow best practices:
 
trigger SOSCreateCaseCustom on SOSSession (after insert) {
    
	List<Case> cList = new List<Case>();
	Map<String, Contact> conMap = new Map<String, Contact>();
	Set<String> emailIdSet = new Set<String>();
	
	for(SOSSession s : Trigger.new) {
		if(s.AppVersion != null && s.AppVersion != '')
			emailIdSet.add(s.AppVersion);
	}
	
	if(!emailIdSet.isEmpty()) {
		for(Contact con: [SELECT Id, Email from Contact WHERE Email IN: emailIdSet]) {
			conMap.put(con.Email, con);
		}
	}
		
    for(SOSSession s : Trigger.new) {
		
		Case caseToAdd = new Case();
		caseToAdd.Subject = 'SOS Video Chat';
		if (s.ContactId != null) {
			caseToAdd.ContactId = s.ContactId;
		} else {
			if(conMap.get(s.AppVersion) != null) {
				caseToAdd.ContactId = conMap.get(s.AppVersion).Id;
			}
		}
		cList.add(caseToAdd);
    }
	
	if(!cList.isEmpty()) {
		insert cList;
	}
}

Here I am not sure onething is AppVersion, other than that everything looks good from my above code.

Regards,
Mahesh
Eric DelgadoEric Delgado
Thanks Mahesh,
You are awesome! Removing the insert Case did fix the problem. However, when I go through the deployment, the validation fails again with the same error.

Code Coverage Failure
Your organization's code coverage is 4%. 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.
SOSCreateCaseCustom

It doesn't make sense because my triggers should definitely have more than 0% code coverage. Am I missing something?
Mahesh DMahesh D
Hi Eric,

As you are getting the Test Class error, it is not covering any of your Trigger code.
You Org Code coverage is only 4% which is stopping you.

Please provide all your deployment components along with code coverage from sandbox so that I can tell you why it is showing the 4%.

Regards,
​Mahesh
Eric DelgadoEric Delgado
Hi Mahesh,
I created this trigger by following this guide:
https://developer.salesforce.com/docs/atlas.en-us.196.0.sos.meta/sos/service_cloud_guides-auto_case_pop.htm

When I turn on the Code Coverage in force.com IDE, I see the test did cover the trigger as some of the lines in the code are highlighted. I believe that means it is covered.

User-added image
Mahesh DMahesh D
Hi Eric,

Try this:
 
@isTest
private class SOSCreateCaseCustomTest {
    static testMethod void validateSOSCreateCase() {
        String caseSubject = 'SOS Video Chat';

		Contact con = new Contact();
		con.LastName = 'Test Name';
		con.Email = 'test@test.com';
		insert con;
		
        // set up case to add 
        SOSSession s = new SOSSession();
        s.AppVersion = 'test@test.com'; // As you used it in query I used the same email id which I used for Contact creation.
		insert s;

        Case ca = [SELECT Subject, ContactId from Case where Subject =: caseSubject];
        // Test that escaltion trigger correctly escalate the question to a case
        System.assertEquals(s.ContactId, ca.ContactId);
    }
}

Regards,
Mahesh
Eric DelgadoEric Delgado
Hi Mahesh,
I tried replacing my unit test with yours. But it throws exception:

System.AssertException: Assertion Failed: Expected: null, Actual: 0034B000005mTdVQAU
Class.SOSCreateCaseCustomTest.validateSOSCreateCase: line 18, column 1

By the way, I don't think its because the unit test is not correct. I believe there might be something that doesn't pick up the unit tests while deploying. I see the same 4% code coverage before adding this unit test, and there is no changes to the math after I added this new unit test.
Mahesh DMahesh D
Try this:
 
@isTest
private class SOSCreateCaseCustomTest {
    static testMethod void validateSOSCreateCase() {
        String caseSubject = 'SOS Video Chat';

		Contact con = new Contact();
		con.LastName = 'Test Name';
		con.Email = 'test@test.com';
		insert con;
		
        // set up case to add 
        SOSSession s = new SOSSession();
        s.AppVersion = 'test@test.com'; // As you used it in query I used the same email id which I used for Contact creation.
		s.ContactId = con.Id;
		insert s;

        Case ca = [SELECT Subject, ContactId from Case where Subject =: caseSubject];
        // Test that escaltion trigger correctly escalate the question to a case
        System.assertEquals(s.ContactId, ca.ContactId);
    }
}

And regarding the 4% code coverage, can you paste the components which you are deploying.

Regards,
Mahesh
Eric DelgadoEric Delgado
Thanks Mahesh,
This code works, and it bumps up the code coverage to 22% now. But I am still struggling with the deployment. This is the only code I added to the sandbox, but I wonder how to get my code coverage up to 75%. This is really a hedious process for deployment. Any tips on what is the right way to deploy sandbox to production? Preferably without the concern of code coverage unit test? Thanks again!
Eric DelgadoEric Delgado
By the way, it stills shows 0% code coverage for triggers. Is there a special way to unit test for triggers?

Code Coverage Failure
Your organization's code coverage is 21%. 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.
SOSCreateCaseCustom
 
Eric DelgadoEric Delgado
Components:
SOS Session Layout, SOS SessionPage Layout, SOSSession-SOS Session Layout
SOSCreateCaseCustom, Apex Trigger, SOSCreateCaseCustom
SOS_Open_Case_Custom, Visualforce Page, SOS_Open_Case_Custom

User-added image
Mahesh DMahesh D
Please add the Test Class also into the deployment 
Eric DelgadoEric Delgado
How do I add the Test class into the components list? Sorry if it sounds stupid...
Mahesh DMahesh D
Once you create the Outbound chnage set, click on the Add button and select the Apex Class, then select the Test Class.

Regards,
Mahesh
This was selected as the best answer
Mahesh DMahesh D
You can't add to the existing uploaded outbound change set.

Please create a new Outbound change set and try to add it.

Still if you are not able to see then, please paste the images to see.

Regards,
Mahesh
Eric DelgadoEric Delgado
Thanks Mahesh!
I did what you say and it is finally working. I also need to do it by choosing specific unit test to run in order to get it to work.