0

How to write test conditions for try and catch blocks in apex. My code coverage is not 100% by below code. Please help.

Apex class:

public static List<String> getUserName(List<String> currentOwnerValues) {
    List<String> ownerNames = new List<String>();
    for (String currentOwnerValue : currentOwnerValues) {
        String ownerName = currentOwnerValue;
        try {
            User u = [SELECT Id, Name FROM User WHERE FederationIdentifier = :currentOwnerValue];
            if (u != null) {
                ownerName = String.escapeSingleQuotes(u.Name);
            }
        } catch (Exception ex) {
            ownerName = String.escapeSingleQuotes(currentOwnerValue);
        }
        ownerNames.add(ownerName);
    }
    return ownerNames;
}

Apex Test class:

public static void getUserName() {
    List<User> usersList = new List<User>();
    List<String> ownerList = new List<String>();
    controller.getUserName(ownerList);
    User u = new User();
    u.FederationIdentifier = '123456';
    usersList.add(u);
    for (User u1 : usersList) {
        ownerList.add(u.FederationIdentifier);
    }
    controller.getUserName(ownerList);
}
1
  • Usefulness of the try/catch aside, you have a query inside of a loop. That's bad, and you should fix that. There is no justification for running this query in a loop.
    – Derek F
    Mar 3 at 11:37

2 Answers 2

2

Will the exception ever actually occur? For conditions you don't plan on happening best not to add exception handling and allow the exception to pass up and be reported.

If the exception handling is part of the required logic, add to the code under test:

@TestVisible private static Boolean GENERATE_EXCEPTION_FOR_TEST = FALSE;

...

      if (GENERATE_EXCEPTION_FOR_TEST) {
          Integer i = 1 / 0;
      }

and set that boolean from your test:

ApexClassName.GENERATE_EXCEPTION_FOR_TEST = true;

The idea is that this is fairly self documenting. Do assert that the values returned for the exception case are correct.

Note that this:

User u = [SELECT Id, Name From User WHERE FederationIdentifier =:currentOwnerValue];

will generate an exception when there are no rows so better:

User[] users = [...];
if (users.size() > 0) {
    ... users[0].Name ...

or my preference of:

for (User u : [...]) {
    ... u.Name ...
2

Try to execute your method wrapped in the try-catch block in your unit test method. It will catch the exception and you can assert if it was really caught.

@IsTest
static void testMethodException() {
    Boolean exceptionCaught = false;

    Test.startTest();
    try {
        // this should trigger null pointer exception
        YourClass.getUserName(null);
    } catch (Exception ex) {
        exceptionCaught = true;
    }
    Test.stopTest();

    System.assertEquals(true, exceptionCaught, 'exception was not caught');
}

Update

As Keith suggested in his answer, the exception won't be thrown here. Therefore, if you want to catch an exception, then update your original method like this:

  public static List<String> getUserName(List<String> currentOwnerValues) {
    List<String> ownerNames = new List<String>();

    try {
      List<User> users = [
        SELECT Id, Name
        FROM User
        WHERE FederationIdentifier IN :currentOwnerValues
        WITH SECURITY_ENFORCED
        LIMIT 100
      ];

      if (!users.isEmpty()) {
        for (User user : users) {
          ownerNames.add(user.Name);
        }
      }
    } catch (Exception ex) {
      throw new AuraHandledException(ex.getMessage());
    }

    return ownerNames;
  }
  1. In this case, you will see an exception if the value you pass to the method is empty.
  2. Executing SOQL inside a for loop is a not recommended
  3. In your variant it's very unlikely you will have the exception you expect. I think it can be thrown if you have users without access to the records or fields.
7
  • I have added above code but still it's not 100%
    – user115525
    Mar 3 at 10:08
  • could you add a current apex class in your original question? @user115525 Mar 3 at 10:14
  • Hi, I have added it using getUserName in Apex class heading.Thanks!
    – user115525
    Mar 3 at 10:16
  • @user115525 updated the answer Mar 3 at 10:43
  • 1
    Hi @KeithC it was a suggestion for the question's code. I just meant that your assumption is correct that it won't throw the exception in the current state. Also, I added the AuraHandledException because the class is called "Controller" in the original question, so I assumed it's called from front-end. Mar 3 at 12:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .