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
Integration 39Integration 39 

Opportunity code coverage problem

Hello,
I am getting 71% code coverage. I have to be missing something really simple.

I have posted my test plan and trigger below.

Please let me know if you have any questions.

I would appreciate any help.

== Test Plan ==
@isTest(SeeAllData=false)
private class TestCreateOppTeam{

    @isTest(SeeAllData=false)
    private static void TestCreateOppTeam() {

        Opportunity opp = new Opportunity(Name='Test opp', StageName='stage', Probability = 10, CloseDate=system.today(), Campaign_Medium__c = 'Campaign_Medium__c',Campaign_Name__c = 'Campaign_Name__c',Product__c = '01t90000004q3PH',Call_Centre__c = 'Call_Centre__c');     
        insert opp;
        
        Opportunity [] OL = [select Id from Opportunity where Id = :opp.id];
        
        for (Opportunity o: OL ) {
            UserRole rn=[Select Name from UserRole where Id= :UserInfo.getUserRoleId()];
            String Role = rn.name;
        
            OpportunityTeamMember newTeamMember = new OpportunityTeamMember();
            newTeamMember.OpportunityId = o.id;
            newTeamMember.UserId = UserInfo.getUserId();
        
            if (role != 'Admin') {
                if (role.containsIgnoreCase('TEST WORD')) {
                    newTeamMember.TeamMemberRole = 'Role 1';
                } else {
                    newTeamMember.TeamMemberRole = 'Role 2';
                }
                insert newTeamMember;
            }
        }
    }
}

== Trigger ==
trigger CreateOppTeam on Opportunity (after insert) {
    
    for (Opportunity o: trigger.new) {
        UserRole rn=[Select Name from UserRole where Id= :UserInfo.getUserRoleId()];
        String Role = rn.name;
        
        OpportunityTeamMember newTeamMember = new OpportunityTeamMember();
        newTeamMember.OpportunityId = o.id;
        newTeamMember.UserId = UserInfo.getUserId();
        
        if (role != 'Admin') {
            if (role.containsIgnoreCase('TEST WORD')) {
                newTeamMember.TeamMemberRole = 'Role 1';
            } else {
                newTeamMember.TeamMemberRole = 'Role 2';
            }
        
            insert newTeamMember;
        }
    }
}
Best Answer chosen by Integration 39
Robert_StrunkRobert_Strunk
Please see the following revisions.  Also, please refer to this link on using the system.runAs() command for testing code under different user contexts. 
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm (https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm" target="_blank)

I created a second testmethod that runs under the new context.  You should specify a user profile name in the SOQL statement for the user object.  Ensure you choose a profile that has appropriate CRUD and FLS.
 
== Test Plan ==
@isTest(SeeAllData=false)
private class TestCreateOppTeam{

    @isTest(SeeAllData=false)
    private static void TestCreateOppTeam() {

        Opportunity opp = new Opportunity(
			Name='Test opp', StageName='stage', 
			Probability = 10, CloseDate=system.today(), 
			Campaign_Medium__c = 'Campaign_Medium__c',
			Campaign_Name__c = 'Campaign_Name__c',
			Product__c = '01t90000004q3PH',
			Call_Centre__c = 'Call_Centre__c'
		);
		
        insert opp;
    }
    @isTest(SeeAllData=false)
    private static void TestCreateOppTeam2() {

        Opportunity opp = new Opportunity(
			Name='Test opp', StageName='stage', 
			Probability = 10, CloseDate=system.today(), 
			Campaign_Medium__c = 'Campaign_Medium__c',
			Campaign_Name__c = 'Campaign_Name__c',
			Product__c = '01t90000004q3PH',
			Call_Centre__c = 'Call_Centre__c'
		);
		
		user u = [SELECT id 
					  FROM user 
					  WHERE userRole.name != 'Admin'
					  AND profile.name = ''//Choose a profile that has the appropriate CRUD and FLS
		];
		
		system.runAs(u){
			insert opp;
		}
		
       
    }
}

Also, here is the revised trigger.
 
trigger CreateOppTeam on Opportunity (after insert) {

	list<OpportunityTeamMember> newTeamMembers = new list<OpportunityTeamMember>();

	//Moved outside of the loop for bulkification
	UserRole rn=[Select Name from UserRole where Id= :UserInfo.getUserRoleId()];
	String Role = rn.name;
	
	//Calling getUserId once and only once
	id theUserId = UserInfo.getUserId();	
	
    for (Opportunity o: trigger.new) {
        
        OpportunityTeamMember newTeamMember = new OpportunityTeamMember();
        newTeamMember.OpportunityId = o.id;
        newTeamMember.UserId = theUserId;
        
        if (role != 'Admin') {
            if (role.containsIgnoreCase('TEST WORD')) {
                newTeamMember.TeamMemberRole = 'Role 1';
            } else {
                newTeamMember.TeamMemberRole = 'Role 2';
            }
        
			//Add to collecting instead of DML insert
            newTeamMembers.add(newTeamMember);
        }
    }
	
	//Bulk insert 
	if(newTeamMembers.size() > 0){
		insert newTeamMembers;
	}
}


PLEASE KEEP IN MIND THAT I FREEHANDED ALL OF THIS IN NOTEPAD

SO THERE MAY BE SOME SYNTAX ERRORS.


Hope that helps.  

All Answers

Robert_StrunkRobert_Strunk
Hi Integration 39, 
   After taking a quick look at your code, you have more pressing issues than coverage.  Please review this article on how to properly bulkify your code.  https://developer.salesforce.com/page/Best_Practice%3A_Bulkify_Your_Code (https://developer.salesforce.com/page/Best_Practice%3A_Bulkify_Your_Code" target="_blank)

Specifically, in your trigger you should move:
 
UserRole rn=[Select Name from UserRole where Id= :UserInfo.getUserRoleId()];
	String Role = rn.name;

Those lines outside of your for loop(before).  

You should also move:
insert newTeamMember;
Outside of your for loop(after).

To do this, you will need to create a collection of opportunityTeamMembers and then insert them all at one time after your loop.  
 
Integration 39Integration 39
Thank you for your feedback. I have made the suggested alterations.

Any thoughts on code coverage? It is not possible to deploy without increasing it and I am sure it is something very trivial that i am missing.
Robert_StrunkRobert_Strunk
Not a problem,   

   I will write somehting up real fast and explain my reasoning.  
 
Robert_StrunkRobert_Strunk
Please see the following revisions.  Also, please refer to this link on using the system.runAs() command for testing code under different user contexts. 
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm (https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm" target="_blank)

I created a second testmethod that runs under the new context.  You should specify a user profile name in the SOQL statement for the user object.  Ensure you choose a profile that has appropriate CRUD and FLS.
 
== Test Plan ==
@isTest(SeeAllData=false)
private class TestCreateOppTeam{

    @isTest(SeeAllData=false)
    private static void TestCreateOppTeam() {

        Opportunity opp = new Opportunity(
			Name='Test opp', StageName='stage', 
			Probability = 10, CloseDate=system.today(), 
			Campaign_Medium__c = 'Campaign_Medium__c',
			Campaign_Name__c = 'Campaign_Name__c',
			Product__c = '01t90000004q3PH',
			Call_Centre__c = 'Call_Centre__c'
		);
		
        insert opp;
    }
    @isTest(SeeAllData=false)
    private static void TestCreateOppTeam2() {

        Opportunity opp = new Opportunity(
			Name='Test opp', StageName='stage', 
			Probability = 10, CloseDate=system.today(), 
			Campaign_Medium__c = 'Campaign_Medium__c',
			Campaign_Name__c = 'Campaign_Name__c',
			Product__c = '01t90000004q3PH',
			Call_Centre__c = 'Call_Centre__c'
		);
		
		user u = [SELECT id 
					  FROM user 
					  WHERE userRole.name != 'Admin'
					  AND profile.name = ''//Choose a profile that has the appropriate CRUD and FLS
		];
		
		system.runAs(u){
			insert opp;
		}
		
       
    }
}

Also, here is the revised trigger.
 
trigger CreateOppTeam on Opportunity (after insert) {

	list<OpportunityTeamMember> newTeamMembers = new list<OpportunityTeamMember>();

	//Moved outside of the loop for bulkification
	UserRole rn=[Select Name from UserRole where Id= :UserInfo.getUserRoleId()];
	String Role = rn.name;
	
	//Calling getUserId once and only once
	id theUserId = UserInfo.getUserId();	
	
    for (Opportunity o: trigger.new) {
        
        OpportunityTeamMember newTeamMember = new OpportunityTeamMember();
        newTeamMember.OpportunityId = o.id;
        newTeamMember.UserId = theUserId;
        
        if (role != 'Admin') {
            if (role.containsIgnoreCase('TEST WORD')) {
                newTeamMember.TeamMemberRole = 'Role 1';
            } else {
                newTeamMember.TeamMemberRole = 'Role 2';
            }
        
			//Add to collecting instead of DML insert
            newTeamMembers.add(newTeamMember);
        }
    }
	
	//Bulk insert 
	if(newTeamMembers.size() > 0){
		insert newTeamMembers;
	}
}


PLEASE KEEP IN MIND THAT I FREEHANDED ALL OF THIS IN NOTEPAD

SO THERE MAY BE SOME SYNTAX ERRORS.


Hope that helps.  
This was selected as the best answer