+ Start a Discussion
jacoclockedjacoclocked 

Trigger test case only 71 percent coverage

I need a bit of help writing my first test class.  Below is the code that i've modified for our environment.  I've also included the test case.   I've got my test class working now. I've pasted the updated class below.  I'm having a problem getting more than 71% code converage.  When I look at my code coverage in my trigger my test class doesn't cover the two lines below in bold.  Please advise in how I can ensure these lines are covered in my test case.  Thank you in advance for any help you can provide.   

 

closingprojects.add(p.id);

 

trigger.newmap.get( (id)ar.get('Id')).pse__Is_Active__c.adderror('This is a customer Project - You cannot set project to inactive until all Milestones are closed.');


How do I test these above lines in my test class?
----

The Trigger

 

// Looks at active projects and checks to see if any milestones are open
// If a milestone is open and a user tries to set a project to inactive then return a message to user


trigger OpenMilestoneTrigger on pse__Proj__c (before update) {


// Creates set of all active projects
set<id> closingprojects = new set<id>();
for(pse__Proj__c p:trigger.new)


// if(p.RecordTypeId == '012Z00000000JWKIA2'&&(p.pse__Stage__c=='Completed'&&trigger.oldmap.get(p.id).pse__Stage__c!='Completed'))
// sets the RecordTypeID for the Customer record

if(p.RecordTypeId == '012Z00000000JWKIA2'&&(p.pse__Is_Active__c == false && trigger.oldmap.get(p.id).pse__Is_Active__c == true))


// Adds active projects to the closingprojects set
closingprojects.add(p.id);


// Checks to see if there are any open milestones within the closing projects set
for(AggregateResult ar:[SELECT pse__Project__c Id,COUNT(Id) FROM pse__Milestone__c
WHERE pse__Project__c IN :closingprojects AND pse__Status__c != 'Approved' GROUP BY pse__Project__c])

// If there are open milestones then add them to the newmap and send error to user
trigger.newmap.get( (id)ar.get('Id')).pse__Stage__c.adderror('This is a customer Project - You cannot set project to inactive until all Milestones are closed.');


}

 

----

The Test Class

@isTest (seealldata=true)
private class OpenMilestoneTriggerTestClass {

private static testMethod void validateOpenMilestoneTriggerNegative() {

//setup variables to be used for building projects. Region and Record type are required
//It is important not to hardcode these values as the Id's will differ in production
RecordType rectype = [Select id from RecordType where Name = 'Customer'];
pse__Region__c regtype = [Select id from pse__Region__c where name = 'West' LIMIT 1];

//select pse__Billing_Type__c from pse__Proj__c where pse__Billing_Type__c = 'Time and Materials' limit 1
//Setup the Project Record
pse__Proj__c p = new pse__Proj__c();
p.RecordTypeId = rectype.id;
p.Name='TestProject';
p.pse__Region__c = regtype.id;
p.pse__Billing_Type__c = 'Hybrid';
p.pse__Is_Active__c = true;

insert p;

//Setup the Milestone Record
pse__Milestone__c m = new pse__Milestone__c();
m.Name = 'TestMileStone';
m.pse__Project__c = p.ID;
m.pse__Milestone_Amount__c = 0;
m.pse__Target_Date__c = Date.today();

insert m;

Test.startTest();

//Set the project status to inactive
try
{
p.pse__Is_Active__c = false;

}
Catch (System.DMLException e)
{
System.assert(e.getMessage().contains('Project cannot be closed with Open Milestones'));
}
Test.stopTest();
}
private static testMethod void validateOpenMilestoneTriggerPositive() {

RecordType rectype = [Select id from RecordType where Name = 'Customer'];
pse__Region__c regtype = [select id from pse__Region__c where name = 'West'];

//Setup the TestProject2 Record
pse__Proj__c p = new pse__Proj__c();
p.RecordTypeId = rectype.id;
p.Name='TestProject2';
p.pse__Region__c = regtype.id;
p.pse__Is_Active__c = true;
p.pse__Billing_Type__c = 'Time and Materials';

insert p;

//Setup the Milestone2 Record
pse__Milestone__c m = new pse__Milestone__c();
m.Name = 'TestMileStone2';
m.pse__Project__c = p.ID;
m.pse__Milestone_Amount__c = 0;
m.pse__Target_Date__c = Date.today();
m.pse__Actual_Date__c = Date.today();

insert m;

Test.startTest();
//Set the milestone status to approved and the project to inactive
try
{
m.pse__Status__c = 'Approved';
p.pse__Is_Active__c = false;
}
Catch (System.DMLException e)
{
System.assert(e.getMessage().contains('Project can be closed if there are no Open Milestones'));
}
Test.stopTest();
}

private static testMethod void validateOpenMilestoneTriggerClosingProjects() {

RecordType rectype = [Select id from RecordType where Name = 'Customer'];
pse__Region__c regtype = [select id from pse__Region__c where name = 'West'];

//Setup the Project Record
pse__Proj__c p = new pse__Proj__c();
p.RecordTypeId = rectype.id;
p.Name='TestProject3';
p.pse__Region__c = regtype.id;
p.pse__Is_Active__c = false;
p.pse__Billing_Type__c = 'Time and Materials';

pse__Milestone__c m1 = new pse__Milestone__c();
m1.Name = 'TestMileStone1';
m1.pse__Project__c = p.ID;
m1.pse__Milestone_Amount__c = 0;
m1.pse__Target_Date__c = Date.today();
m1.pse__Actual_Date__c = Date.today();

insert m1;

pse__Milestone__c m2 = new pse__Milestone__c();
m2.Name = 'TestMileStone2';
m2.pse__Project__c = p.ID;
m2.pse__Milestone_Amount__c = 0;
m2.pse__Target_Date__c = Date.today();
m2.pse__Actual_Date__c = Date.today();

insert m1;



set<id> closingprojects = new set<id>();


// for(AggregateResult ar:[SELECT pse__Project__c Id,COUNT(Id) FROM pse__Milestone__c
// WHERE pse__Project__c IN :closingprojects AND pse__Status__c != 'Approved' GROUP BY pse__Project__c])

// trigger.newmap.get( (id)ar.get('Id')).pse__Is_Active__c.adderror('This is a customer project with a billing type of time and materials - You cannot set project to inactive until all milestones are closed.');


Test.StartTest();
Try
{
if(p.RecordTypeId == rectype.id &&(p.pse__Is_Active__c == false))
closingprojects.add(p.id);
}
Catch (System.DMLException e)
{
System.assertEquals(closingprojects.size(),1);
}
Test.StopTest();

}
}

Best Answer chosen by Admin (Salesforce Developers) 
Platy ITPlaty IT

I think you're on the right track here and the only thing you're missing are "update" statements in your try/catch structures to actually fire your trigger and hit your error conditions.  For example, in the first try/catch after "p.pse__Is_Active__c = false;", do "update p;".  

 

Also, when you use a System.assert in a Catch like that, the assert is only hit if there is an error.  Which means, if no error is hit (and in your case you want it to be), the test won't even hit that statement and no error will still result in a successful test.  So you can create a Boolean variable before the try/catch, like "Boolean isErr = false;", set isErr to true in your Catch and then do a system assert after the Catch.  

 

I think those two changes will do it, but let us know and I can take a closer look if not.

All Answers

Platy ITPlaty IT

I think you're on the right track here and the only thing you're missing are "update" statements in your try/catch structures to actually fire your trigger and hit your error conditions.  For example, in the first try/catch after "p.pse__Is_Active__c = false;", do "update p;".  

 

Also, when you use a System.assert in a Catch like that, the assert is only hit if there is an error.  Which means, if no error is hit (and in your case you want it to be), the test won't even hit that statement and no error will still result in a successful test.  So you can create a Boolean variable before the try/catch, like "Boolean isErr = false;", set isErr to true in your Catch and then do a system assert after the Catch.  

 

I think those two changes will do it, but let us know and I can take a closer look if not.

This was selected as the best answer
jacoclockedjacoclocked

Thanks for the feedback. I'll poke at it some more.