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
Amol Jadhav 9Amol Jadhav 9 

Apex test class with Opportunity and Task

Hello All,
I have written trigger on opportunity, which will display error message if user try to chnage the opportunity stage and for same opportunity there will be Task available with Status not equal to 'Complted'

Trigger
-------------------
trigger ShowErrorMsgOnOpportunity on Opportunity (after update) {
    if(checkRecursive.runOnce()){
        List<Opportunity> countOpenTask = [Select Id, Name, 
                                           (Select Id, Status, WhoId 
                                            From OpenActivities 
                                            Where Status != 'Completed')OppoTask 
                                           From Opportunity 
                                           where Id IN: Trigger.new
                                          ];
        for(Opportunity op : countOpenTask){
            if(op.OpenActivities.size() != 0){
                Trigger.newMap.get(op.Id).addError('Please Close Open Activities to update...');
            }   
        }
        update countOpenTask;
    }
}


And Test Class is
-----------------------
 
@isTest
public class ShowErrorMsgOnOpportunity_Test {
    
    @isTest
    private static void WhenThereAreNoTaskRelatedToOpportunity_ShouldThroughError(){
        String errorMsg = 'Please Close Open Activities to update...';
        
        Test.startTest();
        try{
            
            Account acc = new Account(Name = 'Test Account');
            insert acc;
            
            Opportunity opp = new Opportunity();
            opp.Name = 'Test Opportunity';
            opp.StageName = 'Prospecting';
            opp.CloseDate = Date.today();
            opp.AccountId = acc.Id;
            insert opp;
            
            Task tsk = new Task(WhatId = opp.Id, Subject = 'Test Subject', Status = 'In Progress');
            insert tsk;
            
            update opp;
        }
        
        catch(Exception exc){
            System.assertEquals(exc.getMessage(), errorMsg);
        }
        Test.stopTest();
    }
}

I m not able to cover " if(op.OpenActivities.size() != 0){ Trigger.newMap.get(op.Id).addError('Please Close Open Activities to update...'); } ". Please let me know where I am getting wrong.
Best Answer chosen by Amol Jadhav 9
Jeremy Anderson 14Jeremy Anderson 14
The problem here is, you shouldn't be updating the record from a trigger on the same record.

What you need to do is :


​*** START ***

trigger ShowErrorMsgOnOpportunity on Opportunity (before update) {

set<Id> oppIds = new set<Id>();
for( Opportunity o :trigger.new ){
oppIds.add(o.Id);
}

List<Opportunity> countOpenTask = [Select Id, Name, (Select Id, Status, WhoId From OpenActivities Where Status != 'Completed')OppoTask From Opportunity where Id IN: oppIds ];

map< Id, Integer > oppsById = new map< Id, Integer >();
for(Opportunity o: countOpenTask)
{
oppsById .put(o.Id, o.OpenActivities.size() );
}
for( Opportunity o :trigger.new ){
if(oppsById.get(o.Id) != 0) o.addError('Please Close Open Activities to update...'); 
}


*** END ***

If this doesn't work, email me @ Gijeremy@gmail.com

Cheers,
Jeremy

All Answers

GouthamGoutham
Hi  Amol Jadhav,

Before updating Opportunity record in test class change any field value and then update it.
 
Amol Jadhav 9Amol Jadhav 9
Hi GeethaGoutham I have done the similar thing. 
GouthamGoutham
Try this,

@isTest
public class ShowErrorMsgOnOpportunity_Test {
    
    @isTest
    private static void WhenThereAreNoTaskRelatedToOpportunity_ShouldThroughError(){
        String errorMsg = 'Please Close Open Activities to update...';
        
        Test.startTest();
        try{
            
            Account acc = new Account(Name = 'Test Account');
            insert acc;
            
            Opportunity opp = new Opportunity();
            opp.Name = 'Test Opportunity';
            opp.StageName = 'Prospecting';
            opp.CloseDate = Date.today();
            opp.AccountId = acc.Id;
            insert opp;
            
            Task tsk = new Task(WhatId = opp.Id, Subject = 'Test Subject', Status = 'In Progress');
            insert tsk;
            
            opp.CloseDate = Date.today().addDays(1);
            update opp;
        }
        
        catch(Exception exc){
            System.assertEquals(exc.getMessage(), errorMsg);
        }
        Test.stopTest();
    }
}
Amol Jadhav 9Amol Jadhav 9
Hi GeethaGoutham,
It hasn't worked.
GouthamGoutham
Trigger.New doesn't contain List of IDs. So, change the query.
Use

Set<ID> oppIds = new Set<ID>();
for(Opportunity opp : Trigger.new){
    oppIds.add(opp.id);
}

List<Opportunity> countOpenTask = [Select Id, Name, (Select Id, Status, WhoId From OpenActivities Where Status != 'Completed') From Opportunity where id IN :oppIds]; 
Amol Jadhav 9Amol Jadhav 9
I have also did the solution which you shared but the same issue remains.
Jeremy Anderson 14Jeremy Anderson 14
The problem here is, you shouldn't be updating the record from a trigger on the same record.

What you need to do is :


​*** START ***

trigger ShowErrorMsgOnOpportunity on Opportunity (before update) {

set<Id> oppIds = new set<Id>();
for( Opportunity o :trigger.new ){
oppIds.add(o.Id);
}

List<Opportunity> countOpenTask = [Select Id, Name, (Select Id, Status, WhoId From OpenActivities Where Status != 'Completed')OppoTask From Opportunity where Id IN: oppIds ];

map< Id, Integer > oppsById = new map< Id, Integer >();
for(Opportunity o: countOpenTask)
{
oppsById .put(o.Id, o.OpenActivities.size() );
}
for( Opportunity o :trigger.new ){
if(oppsById.get(o.Id) != 0) o.addError('Please Close Open Activities to update...'); 
}


*** END ***

If this doesn't work, email me @ Gijeremy@gmail.com

Cheers,
Jeremy
This was selected as the best answer
Amol Jadhav 9Amol Jadhav 9
Thanx Jeremy, It worked for me :)