0

There are Three custom objects

  1. Property__c
    Fields: Name, Region__c, site__c
  2. Deal__c
    Fields: Name, Type__c,Manager__c,Property__c
  3. Project__c
    Fields: Name, OwnerId,Deal__c

// all objects has master detail relationship to each other

Custom Settings has been created to store to User id of specific Region__c (to avoid hard coding Id's)

Trigger Logic on Deal__c Custom object:
If Type__c = 'New'
then create a new Project__c Record

BUT Don't inser duplicate Records(check for Name field)

//There are some Deal__c records with Manager__c = Null value; in that situation, //we need to check for Region__c field on Property__c object and then assign the record to particular user

so If Manager__c from Deal__c object is NULL && Region__c from Property__c = 'Asia'

then create a Project__c record with OwnerId as Custom_Settings__c.Asia__c (field taken from custom settings

This is my Trigger

trigger TPTrigger on Deal__c (after insert, after update) {
set<id> DealIds = trigger.newMap.keyset();
List <Project__c> Project = [select id, 
Name,Deal__r.Property__r.Region__c,Property__r.Site__c from Project__c where 
id in :DealIds];
List <Project__c> NewProject = new List<Project__c>();
for(Deal__c deal : 
   [Select id,Name,
Property__r.Region__c,
Type__c,Status__c,
Manager__c,
Property__r.Site__c 
from 
Deal__c where id IN :DealIds]){
    If(deal.Type__c == 'New')
    {
    // initiating the string to check for duplicate records 
        string Name = deal.Name + ' - ' + deal.Property__r.Site__c;
        List <Project__c> ProjectList = [select id,Name,OwnerId,Property__r.Site__c from Project__c where Name =: Name];
        //have stored User Id in custom settings 
        CustomSettings__c user = CustomSettings__c.getInstance(Userinfo.getUserId());
        if (ProjectList.size() == 0)
            {
             if(deal.Manager__c == Null) 
                {
                 if(deal.Property__r.Region__c == 'Asia')
                 {
                    deal.Manager__c = user.Asia__c;
                 }//else if 
                    }//if
             NewProject.add(new Project__c
                              (Name = deal.Name + ' - ' + deal.Property__r.Site__c, 
                               OwnerId = deal.Manager__c
                               ));

            insert NewProject;
}//if
        else if ((ProjectList.size() > 0))
        {
            if(deal.Manager__c == Null)
            {
                if(deal.Property__r.Region__c == 'Asia')
                {
                    deal.Manager__c = user.Asia__c;
                }
            }
            Project__c NewProjectList = [select id,Name from Project__c where Name =: Name];
            NewProjectList.OwnerId = deal.Manager__c; 
            update NewProjectList;
        }
    }
   }
}

Test Class:

  @isTest(SeeAllData=true)
  private class TPTrigger_test {
  static testmethod void Create(){
    Property__c prop_MA = new Property__c(Name = 'Test MA Name ', Site__c = ' 
   test MA site ', Region__c = 'Asia');
    insert prop_MA;
    system.debug(prop_MA);
    Profile objProfile_Mid = [SELECT Id, Name FROM Profile WHERE Name='System 
    Administrator'];
    User objUser_Mid = new User(Alias = 'silly', 
                            many more fields );
    insert objUser_Mid; 

    Deal__c deal_MA = new LMS_Deal__c(Name = 'Test deal',
                                      Manager__c = objUser_Mid.Id,
                                      Type__c = 'New');
    insert deal_MA;
    system.debug(LMSdeal_MA);
    CustomSettings__c users = 
     CustomSettings__c__c.getInstance(Userinfo.getUserId());    
        system.debug(users);
        Project__c p = new Project__c() ;
            p.Name = deal_MA.Name +  ' - '  + Prop_MA.Site__c;
            p.OwnerId = deal_MA.Manager__c;

        insert p ;
        system.debug(p);
        if((deal_MA.Manager__c == Null)
            &&
           (Prop_MA.Region__c == 'Asia'))
            {
                p.OwnerId = users.Asia__c;
            }
        update p;
    // create new string for duplicate names 
    String Name_MA = deal_MA.Name + ' - ' + Prop_MA.Site__c;
    system.debug(Name_MA);
    List<Project__c> legits = [SELECT Id,Name FROM Project__c WHERE Name 
    =:Name];
   System.assertEquals(1, legits.size());
    }          
    }

The below lines are in Red (Not able to pass the values)

   if (ProjectList.size() == 0)
            {
             if(deal.Manager__c == Null) 
                {
                 if(deal.Property__r.Region__c == 'Asia')
                 {
                    deal.Manager__c = user.Asia__c;
                 }//else if 
                    }//if
             }
  • 1
    There are quite a few logical problems with this code and its test case, but the custom setting actually is not the cause of your code not covering those lines. You can construct and insert a custom setting in a test context just like any other sObject, but your coverage issue is related to making sure that your test data matches the criteria in your code to execute that logical path. – David Reed Jan 23 at 14:13
  • From UI testing perspective it's working as desired Sir. – Doondi Jan 23 at 14:33
  • Sir, Please advise, shall I change the code or test class? – Doondi Jan 24 at 7:31
1

You've identified a problem with your test class - you don't create and insert a CustomSettings__c instance in test context - but it's not the problem that is causing your code coverage not to reach the lines you expect it to.

You need to write multiple unit tests to cover different logical paths in your trigger, ensure that your test data matches the criteria in your code to enter that path, and ensure that the related data upon which your logic depends is present.

Here, you have different logic that executes based upon whether or not Project__c records are found for the updated Deal__c, and you have specific requirements for one of the logic branches - the field Deal__c.Type__c must equal 'New'. You do create test data that appears to meet that criterion.

However, you have two other problems that take hold here.

One, you use a data point in your code that your unit test does not provide.

    string Name = deal.Name + ' - ' + deal.Property__r.Site__c;

The Property__c lookup on your test Deal__c is blank, so deal.Property__r.Site__c is null here. Now one would think that that would just return no results and hence execute your code, but ...

@isTest(SeeAllData=true)

You are using the annotation that should virtually never be used, and exposing all of your org's data to your unit test. This makes it very difficult to predict the behavior of the code when unrestricted queries are run like this, and is why ProjectList.size() != 0 here - presumably, the query is matching some record that exists in your org, but is not related to this test.

There is another issue that is masking this mistake. You are creating a tautological assertion - an assertion basically that "A = A". You create and insert the Project__c record, in your test class, that your trigger is supposed to insert, and then query for that same record and assert that it exists. This is creating a false positive - a passing assertion that actually proves nothing.

    Project__c p = new Project__c() ;
        p.Name = deal_MA.Name +  ' - '  + Prop_MA.Site__c;
        p.OwnerId = deal_MA.Manager__c;

    insert p ;

Note that here you create your Project__c to match your criteria, even though you haven't linked deal_MA and Prop_MA together for your trigger to find when it executes its query.

String Name_MA = deal_MA.Name + ' - ' + Prop_MA.Site__c;
system.debug(Name_MA);
List<Project__c> legits = [SELECT Id,Name FROM Project__c WHERE Name 
=:Name];
System.assertEquals(1, legits.size());

Here you're simply asserting that the record your test class already created exists. This is worse than useless, because it hides the fact that your trigger's test is broken.

You need to write real assertions against the work that your trigger is doing, and you need to write more than one unit test (without seeAllData=true) to validate the several code paths that you have here for different insert and update situations.

Lastly... you can create a CustomSettings__c object just like an sObject:

CustomSettings__c c = new CustomSettings__c();

Populate its fields with data, including the field SetupOwnerId if this is a hierarchy setting, as it appears to be, and insert it into the database.

insert c;

You need to do this, though, before you fire your trigger by doing an insert on a Deal__c, so the Custom Setting is available once the trigger executes.

  • Sir, I have created another test class without seeAlldata I have created custom settings as you said and inserted SetupOwnerId, Name & Asia__c - This part is fine BUT I am not able to insert deal__c : below is the error causing by oldTrigger on same Object: System.DmlExce: Insert failed. first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, olddealTrigger: exe.. of BeforeInsert – Doondi Jan 24 at 6:25
  • Hi Doondi, I think that is really a separate issue and you're welcome to open a new question if you're not able to debug it yourself. The message you pasted here is abbreviated, so the actual error is not clear. – David Reed Jan 24 at 12:48
  • Sir, at least help in with (setAlldata=ture) , If setalldata=true then I am getting good coverage for If conditions BUT only custom settings are failing. Pls sir, some light on this, I am completely stuck. – Doondi Jan 24 at 12:51
  • You should never write a test class with seeAllData=true unless you are working with the Chatter API or using advanced dependency injection techniques. I've provided quite a bit of detail above on what I think you need to do. If there is something you would like me to explain further, I'm happy to expand it. – David Reed Jan 24 at 12:59

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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