1

I am very new to Apex, and trying to learn the ropes. I was hoping if anyone could help me with my Test Class for a custom controller. I have read bunch of documentation, but I am still not able to get %100 coverage in my code. For some reason my test class does not test any of my custom controller queries.

Here is the controller:

   public with Sharing class SprintTasksCon{
private String sortOrder = 'Name';


        public Story__c s { get;set; }
        public Sprint__c sp { get;set; }
        public Story_Task__c stt { get;set; }
        Date target_date = Date.today();

        public List <Story_Task__c> getStoryTasks{get;set;}
        public List <Sprint__c> getCurrentSprint{get;set;}



            public void filterStoryTask(){
            //getStoryTasks = new List<Story_Task__c>();
            getStoryTasks.clear();
                  if(stt.Owner__c !=null && s.Sprint__c!=null){
                      getStoryTasks = [Select Id, Name, Owner__r.Name, Story__r.Name, Subject__c, Story__r.Sprint__r.Name
                                     FROM Story_Task__c 
                                     WHERE Owner__c=:stt.Owner__c AND Story__r.Sprint__c=:s.Sprint__c Limit 100];
                  } 
                  else if(s.Sprint__c == null){
                     getStoryTasks = [Select Id, Name, Owner__r.Name, Story__r.Name, Subject__c, Story__r.Sprint__r.Name
                                     FROM Story_Task__c 
                                     WHERE Owner__c=:stt.Owner__c Limit 100];
                  } 
                  else if(stt.Owner__c == null){
                     getStoryTasks = [Select Id, Name, Owner__r.Name, Story__r.Name, Subject__c, Story__r.Sprint__r.Name
                                     FROM Story_Task__c 
                                     WHERE Story__r.Sprint__c=:s.Sprint__c Limit 100];
                  }

                  else{
                      getStoryTasks = [Select Id, Name, Owner__r.Name, Story__r.Name, Subject__c, Story__r.Sprint__r.Name
                                     FROM Story_Task__c Limit 100];
                 }

                if (getStoryTasks.isEmpty())
                  {
                   ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR,'No records found');
                   ApexPages.addMessage(myMsg); 
                  }
            }




        public SprintTasksCon(){
            stt = new Story_Task__c();
            s = new Story__c();

            getCurrentSprint = [Select Id, Name, Start_Date__c, End_Date__c, Story_Points__c, Velocity__c
                                FROM Sprint__c target_date
                                WHERE Start_Date__c <: target_date AND End_Date__c >: target_date Limit 5]; 

           if (getCurrentSprint.isEmpty())
                  {
                   ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR,'No records found');
                   ApexPages.addMessage(myMsg); 
                  }


            getStoryTasks = new List<Story_Task__c>();
            getStoryTasks = [Select Id, Name, Owner__r.Name, Story__r.Name, Subject__c, Story__r.Sprint__r.Name
                            FROM Story_Task__c 
                            Where Story__r.Sprint__r.Start_Date__c <: target_date AND Story__r.Sprint__r.End_Date__c >: target_date 
                            Limit 100];


        }   

}

Here is my current Test Class. I get only %75 coverage at this point. The lines I get that are not tested are for the filterStoryTasks method. I think I am trying to test that in my test class, but I guess I am not sure why not.

@isTest
public class SprintTasksConTest {


    public static testMethod void testMyController(){

        Profile pf = [Select Id from Profile where Name='System Administrator'];
        User newUser = new User(
                        LastName='test123',
                        IsActive=true,
                        ProfileId=pf.id,
                        LanguageLocaleKey='en_US',
                        EmailEncodingKey='UTF-8', 
                        LocaleSidKey='en_US',
                        Alias='test1', 
                        TimeZoneSidKey='America/Los_Angeles', 
                        CommunityNickname='test1', 
                        Username=String.valueOf(math.random()) + 'User123test1@test.com', 
                        Email='testUser1@gmail.com');
         insert newUser;

        Sprint__c testSprint = new Sprint__c();
        testSprint.Name ='Test Sprint';
        testSprint.Start_Date__c = Date.Today().addDays(4);
        testSprint.End_Date__c = Date.Today().addDays(-4);
        insert testSprint;


        Test.StartTest();
            PageReference pageRef = Page.SprintTasks;
            pageRef.getParameters().put('stt.Owner__c', String.valueOf(testSprint.id));
            pageRef.getParameters().put('s.Sprint__c', String.valueOf(newUser.Name));
            Test.setCurrentPage(pageRef);


            SprintTasksCon controller = new SprintTasksCon();
            controller.filterStoryTask();
            //controller = new SprintTasksCon();
            //controller = setSprint__c ('test');

        Test.StopTest();
    }

}
1

It is vitally important that you understand the end goal of Unit Tests is not to cover lines of code, but to verify application behavior. See, for example, How to Write Good Unit Tests (emphasis mine):

Verify the results are correct

Verifying that your code works as you expect it to work is the most important part of unit testing. It’s also one of the things that Force.com developers commonly neglect. Unit tests that do not verify the results of the code aren’t true unit tests. They are commonly referred to as smoke tests, which aren’t nearly as effective or informative as true unit tests.

A good way to tell if unit tests are properly verifying results is to look for liberal use of the System.assert() methods. If there aren’t any System.assert() method calls, then the tests aren’t verifying results properly. And, no, System.assert(true); doesn’t count.

Without learning to write good assertions, you are entirely missing the point of Unit Testing.


That said, your testing strategy itself needs an update. You need a separate test method for each branch of this logical chain:

if(stt.Owner__c !=null && s.Sprint__c != null)
{
    // logic to be executed
}
else if(s.Sprint__c == null)
{
    // logic to be executed
}
else if(stt.Owner__c == null)
{
    // logic to be executed
}
else
{
    // logic to be executed
}

In each test method, you need to set the relevant properties on your Story_Task__c record.

static testMethod void testFilterStoryTask_BothPopulated()
{
    SprintTasksCon controller = new SprintTasksCon();
    controller.stt.Owner__c = '<some_value>';
    controller.s.Sprint__c = '<some_value>';

    Test.startTest();
        // call filter method
    Test.stopTest();

    // add assertions
}
static testMethod void testFilterStoryTask_OwnerNull()
{
    SprintTasksCon controller = new SprintTasksCon();
    // do not set controller.stt.Owner__c = '<some_value>';
    controller.s.Sprint__c = '<some_value>';

    // rest of test
}
static testMethod void testFilterStoryTask_SprintNull()
{
    SprintTasksCon controller = new SprintTasksCon();
    controller.stt.Owner__c = '<some_value>';
    // do not set controller.s.Sprint__c = '<some_value>';

    // rest of test
}
static testMethod void testFilterStoryTask_BothNull()
{
    SprintTasksCon controller = new SprintTasksCon();
    // do not set controller.stt.Owner__c
    // do not set controller.s.Sprint__c

    // rest of test
}

True, you could just go through all of these controller states in one unit test method, but remember that the terminology itself ("unit") implies that you should strive to test a single operation in each test.

2
  • 1
    Thank you Adrian. This is very helpful to understand the process better.
    – Ivo Dimov
    Apr 13 '17 at 15:16
  • @Ivo That linked document is really worth the read, and I suggest you read the whole thing. I also highly recommend Testing Best Practices.
    – Adrian Larson
    Apr 13 '17 at 15:17

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.