2

So I've been reading and noticed that as a general rule you should shoot for 75-90% code coverage for a trigger, aiming for 90% or higher if possible.

I feel proud of myself for getting the test coverage to pass. But I cannot for the life of me get it to resolve beyond 16%.

The purpose of the trigger (and it works doing this) is so that when an IT Request lands in the IT Request object, it makes a duplicate of in TaskRay. I also have a trigger that updates the IT Request when it's updated in TaskRay, and perpetuates the data. That one I have working, with 100% code coverage. But I am very lost on why the below won't get above 16%.

trigger VS_ITRequestToTaskRay on IT_Request__c (after insert){
//Needs to be bulkified
List<TASKRAY__Project_Task__c> toCreate = new List<TASKRAY__Project_Task__c>();
TASKRAY__Project__c reqID = [SELECT Id, Name FROM TASKRAY__Project__c WHERE Name = 'IT Requests'];


for(IT_Request__c trt : Trigger.new)

{
    TASKRAY__Project_Task__c toTaskRay = new TASKRAY__Project_Task__c();

    toTaskRay.IT_Request__c = trt.Id;   
    toTaskRay.TASKRAY__Description__c = 'Type: ' + trt.Type__c + '. Notes: ' + trt.Remarks__c;
    toTaskRay.Name = 'ITREQ - ' + trt.Requestor_Name__c + ' - ' + trt.Subject__c +' - ' + trt.Reason__c;
    toTaskRay.TASKRAY__List__c = 'Holding';
    toTaskRay.TASKRAY__Project__c = reqID.Id;

    toCreate.add(toTaskRay);

}
insert toCreate;

}

I have no idea if that is bulkified correctly or not, but I did try to set it up by adding each loop result to a list, then updating the list. (I've only been learning Apex for about 3 weeks now, and am still a bit confused about bulkify, though it's starting to make sense.)

My test class it this:

@isTest
public class itRequestToTaskRay {
private static void genData()
  {
    IT_Request__c testRequest = new IT_Request__c();
    testRequest.Requestor_Name__c = 'Mister Anderson';
    testRequest.Type__c = 'Fix';
    testRequest.Subject__c = 'Salesforce';
    testRequest.Reason__c = 'Administrator Needed';
    testRequest.Remarks__c = 'Wake up, Neo.';
    insert testRequest;
  }


public static testMethod void testValues()
{
    try 
    {
        genData();
        IT_Request__c matchAgainst = [SELECT Id, Name, Requestor_Name__c, Remarks__c FROM IT_Request__c WHERE Requestor_Name__c = 'Mister Anderson' LIMIT 1];
        TASKRAY__Project_Task__c resultCheck = [SELECT Id, Name, IT_Request__c, TASKRAY__Description__c, TASKRAY__List__c, TASKRAY__Project__c 
                                                FROM TASKRAY__Project_Task__c 
                                                WHERE IT_Request__c = : matchAgainst.Id LIMIT 1];
        Test.startTest();
        //find effective way to not repeat self
        System.assert(resultCheck.IT_Request__c == matchAgainst.Id);
        System.assert(resultCheck.Name != null);
        System.assert(resultCheck.TASKRAY__List__c == 'Holding');
        System.assert(resultCheck.TASKRAY__Project__c == [SELECT Id, Name FROM TASKRAY__Project__c WHERE Name = 'IT Requests'].Id);

        Test.stopTest();
    } 
    catch (DmlException dmle)
    {
        System.debug(dmle);
    }
}


}

Edit: I marked the answer, but also just wanted to post my notes here about what it ultimately was.

1) Remove catch/try as it was preventing me from seeing the errors I need to see. This had to do with data that could not be returned from a SOQL query.

2) The SOQL query returned no data because a test class cannot query data from the live org, or rest of the sandbox. The test class can ONLY see data that is created in the test class. You have to create it all: Contact, Project, User, whatever you need to run your test class.

3) Duplicate's in production won't be an issue within a test class. The test class starts with empty data, and you can populate users with names, or projects with names, that are the same as ones in production/sandbox, and you won't run into any issues so long as the data is created within the test class itself.

  • 2
    Definitely remove your try/catch block. It's just suppressing errors that you need to see. – Adrian Larson Jun 23 '16 at 21:30
  • @AdrianLarson I removed the catch try, and it pointed to the line that Daniel Ballinger mentioned below. – Genko Jun 23 '16 at 21:50
  • 2
    This is unrelated, but since you are asking for some help I thought I'd offer some unsolicited advice. When asserting, always prefer using assertEquals and assertNotEquals. Also, add a second clause with a descriptive error message. The advantages are many, most important that if the assert doesn't work you'll get a much more descriptive error message. As an example, you can do System.assertEquals('Holding', resultCheck.TASKRAY__List__c, 'List Values Arent Matching); – Sebastian Kessel Jun 23 '16 at 21:55
  • 1
    @SebastianKessel Thank you, that actually answered something else I hadn't gotten around to asking yet, but have been rolling around in my head trying to resolve for a few hours now... Thanks for freeing up some of my brain cells :) – Genko Jun 23 '16 at 22:01
5

The problem is likely that the trigger depends on a record that isn't available in a testing context.

The following looks like the suspect:

TASKRAY__Project__c reqID = [SELECT Id, Name FROM TASKRAY__Project__c WHERE Name = 'IT Requests'];

Try inserting a TASKRAY__Project__c record with the Name 'IT Requests' as part of the test setup.

Also, as Adrian commented, ditch the try/catch in your testMethod. It is swallowing the exception that would otherwise make the test fail (which it should) and show the underlying problem.

  • 2
    Welcome to lesson 1 in the school of hard knocks testing :) Test cases can't see live data in an org. The test cases run in isolation and must script in any data they require. Now there is the @IsTest(SeeAllData=true) annotation, but I was hesitant to even bring it up. First you should learn to make test cases that are self contained. Only in exceptional circumstances should a test case depend of live data from an org. – Daniel Ballinger Jun 23 '16 at 21:52
  • 2
    @Genko See also Why Are Data Silos Important in Unit Tests? – Adrian Larson Jun 23 '16 at 21:53
  • 1
    @DanielBallinger Thanks for the advice! That makes sense, and answers a couple of things. I'll shy away from (SeeAllData=true) until I actually learn how to do test cases properly. (I enjoy the challenge). And thanks for the helpful reading. If I'm understanding you correctly, then SOQL queries from within a test class will only return the data we've created in that test class, because it's all that it can see, right? – Genko Jun 23 '16 at 21:57
  • 2
    @Genko Yes, that is correct. Using SeeAllData=true can make the tests overly dependent on the org they are running in. It can make it difficult to move code from one org to another. Also, tests could just start failing if the required records are changed or deleted. – Daniel Ballinger Jun 23 '16 at 22:01
  • 2
    @DanielBallinger Wanted to let you know, once I generated all the necessary data within the test class it completed with 100% code coverage. Thanks again! – Genko Jun 23 '16 at 22:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.